<div> <header> <slot></slot> </header> <main> <slot></slot> </main> <footer> <slot></slot> </footer> </div>
而在父组件模板中:
<app-layout> <h1 slot="header">这里大概是一个页面标题</h1> <p>主要内容的一个段落。</p> <p>另一个段落。</p> <p slot="footer">这里有一些接洽信息</p> </app-layout>
最终渲染的功效:
<div> <header> <h1>这里大概是一个页面标题</h1> </header> <main> <p>主要内容的一个段落。</p> <p>另一个段落。</p> </main> <footer> <p>这里有一些接洽信息</p> </footer> </div>
插槽分发的长处表此刻,它可以让组件具有可抽象成模板的本领。组件自身只体贴模板布局,详细的内容交给父组件去处理惩罚,同时,不冲破HTML描写DOM布局的语法表达方法。我以为这是一项很有意义的技能,惋惜,React对付这项技能的支持不是那么友好。于是我便参考Vuejs的插槽分发组件,开拓了一套基于React的插槽分发组件,可以让React组件也具模板化的本领。
对付<AppLayout />组件,我但愿可以写成下面这样:
class AppLayout extends React.Component { static displayName = 'AppLayout' render () { return ( <div> <header> <Slot></Slot> </header> <main> <Slot></Slot> </main> <footer> <Slot></Slot> </footer> </div> ) } }
在外层利用时,可以写成这样:
<AppLayout> <AddOn slot="header"> <h1>这里大概是一个页面标题</h1> </AddOn> <AddOn> <p>主要内容的一个段落。</p> <p>另一个段落。</p> </AddOn> <AddOn slot="footer"> <p>这里有一些接洽信息</p> </AddOn> </AppLayout>
组件的实现思路按照前面所想的,先整理一下实现思路。
不丢脸出,插槽分发组件需要依靠两个子组件——插槽组件<Slot />和分发组件<AddOn />。插槽组件,认真打桩,提供分发内容的坑位。分发组件,认真收集分发内容,并提供应插槽组件去渲染分发内容,相当于插槽的消费者。
显然,这里碰着了一个问题,<Slot />组件与<AddOn />组件是独立的,如何将<AddOn />的内容填充到<Slot />中呢?办理这个问题不难,两个独立的模块需要成立接洽,就给他们成立一个桥梁。那么这个桥梁要如何搭建呢?回过甚来看看之前的设想的代码。
对付<AppLayout />组件,但愿写成下面这样:
class AppLayout extends React.Component { static displayName = 'AppLayout' render () { return ( <div> <header> <Slot></Slot> </header> <main> <Slot></Slot> </main> <footer> <Slot></Slot> </footer> </div> ) } }
在外层利用时,写成这样:
<AppLayout> <AddOn slot="header"> <h1>这里大概是一个页面标题</h1> </AddOn> <AddOn> <p>主要内容的一个段落。</p> <p>另一个段落。</p> </AddOn> <AddOn slot="footer"> <p>这里有一些接洽信息</p> </AddOn> </AppLayout>
无论是<Slot />照旧<AddOn />,其实都在<AppLayout />的浸染域内。<Slot />是<AppLayout />组件render()要领返回的组件节点,而<AddOn />则是<AppLayout />的children节点,所以,可以将<AppLayout />视为<Slot />与<AddOn />的桥梁的脚色。那么,<AppLayout />通过什么给<Slot />和<AddOn />成立接洽呢?这里就用到本文的主角——Context。接下来的问题就是,如何利用Context给<Slot />和<AddOn />成立接洽?
前面提到了<AppLayout />这座桥梁。在外层组件,<AppLayout />认真通过<AddOn />收集为插槽填充的内容。<AppLayout />自身借助Context界说一个获取填充内容的接口。在渲染的时候,因为<Slot />是<AppLayout />渲染的节点,所以,<Slot />可以通过Context获取到<AppLayout />界说的获取填充内容的接口,然后通过这个接口,获取到填充内容举办渲染。
凭据思路实现插槽分发组件