如何让HTML模板定义与Vue相同的React组件?

时间:2019-05-11 15:18:43

标签: javascript reactjs templates vue.js

在Vue中,您可以拥有类似的东西。

<!-- index.php -->

<div id="app">
    <section>
        <main>
            <h1>Main</h1>
            <some-component></some-component>
        </main>
        <aside>
            <h2>Side</h2>
            <another-component></another-component>
        </aside>
    </section>
</div>

<script>
    Vue.component('some-component', { template: '<div>hello - {{ this.$parent.test }}</div>' });
    Vue.component('another-component', { template: '<div>world - {{ this.$parent.test }}</div>' });

    new Vue({el: '#app', data: () => ({test: 123})});
</script>

这将呈现所有已注册的组件,最终您将得到类似

的信息
<div id="app">
    <section>
        <main>
            <h1>Main</h1>
            <div>hello - 123</div>
        </main>
        <aside>
            <h2>Side</h2>
            <div>world - 123</div>
        </aside>
    </section>
</div>

如何使用React完成同一件事?

我尝试过类似愚蠢的事情

class App extends Component {
    render() {
        return <div>{this.props.kids}</div>
    }
}


if (document.getElementById('app')) {
    ReactDOM.render(<App kids={document.getElementById('app').innerHTML)} />, document.getElementById('app'));
}

总体目标是能够拥有普通的html模板,然后在需要的地方分散各种反应组件。

理想情况下,它应该包含一个类似非渲染的组件,该组件可以使用上下文api提供向下的全局数据。

2 个答案:

答案 0 :(得分:0)

如果您想要vue /类似Angular的模板,我看不到使用React的意义,请改用vue。如果愿意的话,React使用javascript xml或jsx,它们看上去确实像模板,但实际上为您带来了javascript可以做的所有事情的好处。

尽管,如果您希望所有内容都在一个组件中,那么没有什么可以阻止您这样做的。

现在,如果您想让您使用一个可以呈现所有子项的组件,那么您与tbh相距不远。这是codeburst

中的一个简单示例
const Picture = (props) => {
  return (
    <div>
      <img src={props.src}/>
      {props.children}
    </div>
  )
}


render () {
  return (
    <div className='container'>
      <Picture src={picture.src}>
          //what is placed here is passed as props.children  
      </Picture>
    </div>
  )
}

答案 1 :(得分:0)

React不是基于模板的,而是使用JS或JSX定义组件,因此选项受到限制。

最好是

可以使用dangerouslySetInnerHTML渲染HTML代码段:

<div dangerouslySetInnerHTML={this.props.kids}/>

这不允许在代码片段中使用自定义组件,因为React组件不使用选择器。可以使用HTML解析器将模板解析为React元素的层次结构,然后将<some-component>之类的自定义元素替换为this question中所示的相应React组件。

可以在飞行中定义和运输组件,但在生产中不建议这样做:

<script src="https://unpkg.com/babel-standalone/babel.js"></script>
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script type="text/babel">
  var Foo = () => 'Foo';
</script>
...
<script type="text/babel">
  ReactDOM.render(<Foo/>, document.getElementById('foo'));
</script>

为了对多个组件使用上下文API,不应将它们呈现为带有render的根组件,而应呈现在一个公共父组件中,例如,呈现为具有createPortal的门户:

...
<script>
  var portals = {};
</script>
...
<script type="text/babel">
  portals['#foo'] = <Foo/>;
</script>
...
<script type="text/babel">
  // runs on page load
  var CommonContext = ...;
  var Root = () => (
    <CommonContext.Provider value={...}>
      {Object.entries(portals).map(({ selector, child }) => (
        ReactDOM.createPortal(child, document.querySelector(selector))
      )}
    </CommonContext.Provider>      
  );

  ReactDOM.render(<Root/>, document.getElementById('root'));
</script>