插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。插槽的原理和Angular中的ng-transclude十分类似,本篇也是对所学内容做一个梳理。
形式上看,Slot的设计对应了angular中的ng-tranclude
属性,即用该方法来确定在何处放置嵌入部分。
ng-transclude使用
html内容
<my-msg>{{msg}}</my-msg>
模版内容
<div> <p>Here comes the message.</p> <div ng-transclude></div> </div>
渲染结果
<div> <p>Here comes the message.</p> {{msg}} </div>
可以看出,形式上,Angular是把ng-transclude
标签替换为要使用的模板内容。
Slot的使用
匿名slot
举个栗子,在Vue中,我们会这么写带slot的组件:
组件模板
<div> <h2>我是子组件的标题</h2> <slot></slot> </div>
父组件模版
<div> <h1>我是父组件的标题</h1> <my-component> <p>这是一些初始内容</p> <p>这是更多的初始内容</p> </my-component> </div>
渲染结果
<div> <h1>我是父组件的标题</h1> <div> <h2>我是子组件的标题</h2> <p>这是一些初始内容</p> <p>这是更多的初始内容</p> </div> </div>
对比一下,是不是和ng-transclude
十分类似?Slot所做的工作,也是把父组件中的“内容”被放入了slot,并将组合后的组件模版返回到父组件。这里slot
标签里的内容实际并没有显示,被当作了备用内容(只有在宿主元素为空,没有要插入的内容时才显示)。
更进一步地,Vue给出了具名Slot也作用域插槽这两个比较独特的设计。
具名slot
上面栗子中使用的是匿名slot,即该节点不携带任何其也特征信息。对应的,Vue也提供了具名slot。简单来讲,具名Slot就是会为模板中不同部分指定相应的插入位置。但是当部分内容没有找到对应的插入位置,就会依次插入匿名的slot中,当没有找到匿名slot时,这段内容就会被抛弃掉。
组件模版
... <slot name="header"></slot> <slot name="footer"></slot> <slot></slot> ...
父组件模版
... <p>Lack of anonymous slot, this paragraph will not shown.</p> <p slot="footer">Here comes the footer content</p> <p slot="header">Here comes the header content</p> ...
渲染结果
<p>Here comes the header content</p> <p>Here comes the footer content</p> <p>Lack of anonymous slot, this paragraph will not shown.</p>