Vue之深入了解插槽—slot, slot-scope, v-slot, v-slot:[name]=slotProps, $slots, $scopedSlots
| Vue 2.6.0 以前 | Vue 2.6.0 以后 |
|---|---|
具名插槽 slot | 具名插槽 v-slot |
作用域插槽 slot-scope = slotProps | 作用域插槽 v-slot: [name] = slotProps |
这里我们要探讨的不是怎样用,而是比较少有探索的 slot, slot-scope 以及 v-slot, v-slot:[name] = slotProps 与 $slots, $scopedSlots 的关系,一般在应用中不涉及渲染函数,很少用得到$slots和 $scopedSlots,但是在深入了解插槽的实现和二次封装 UI库 的时候即可能用得上了。
一、 slot,slot-scope 和 $slots, $scopedSlots 的关系
1. 无作用域插槽
HTML
<div id="parent-template"> <child> <!--此处是待分发的内容--> <p slot="header">header</p> <p slot="footer">footer</p> <p>default</p> </child></div><template id="child-template"> <div> <slot name="header"></slot> <slot>默认分发处</slot> <slot name="footer"></slot> </div></template>JS
// 注册子组件Vue.component("child", { template:"#child-template", mounted() { console.log('$slots',this.$slots) console.log('$scopedSlots',this.$scopedSlots) }});// 初始化父组件new Vue({ el: "#parent-template"});Console 输出
v2.5.22无作用域插槽.png
v2.6.10无作用域插槽.png
这是一个常用的插槽模板,从这个结果中可以看出v2.6.0以前,slot 和 slot-scope是分开的 ;
v2.6.0以前父组件没有调用 slot-scope 时, $scopedSlots 里面为空 ;
v2.6.0以后 $scopedSlots 里的具名值和 $slots 具名值是逐个对应的。
2. 有作用域插槽
HTML
<div id="parent-template"> <child> <!--此处是待分发的内容--> <p slot="header" slot-scope="{header}">{{ header }}</p> <p slot="footer">footer</p> <p>default</p> </child></div><template id="child-template"> <div> <slot name="header" v-bind:header="'header'"></slot> <slot>默认分发处</slot> <slot name="footer" v-bind:footer="'footer'"></slot> </div></template>
v2.5.22有作用域插槽.png
v2.6.10有作用域插槽
v2.6.0以前,在父组件中’header’具名插槽中调用了slot-scope后,$scopedSlots 中出现了‘header’为key的function, $slots 中‘header’为key的VNode不见了;
v2.6.0以后,在父组件中’header’具名插槽中调用了slot-scope后,$scopedSlots 中没有变化, $slots 中‘header’为key的VNode不见了。
3. 屡次调用同一个具名插槽
HTML
<div id="parent-template"> <child> <!--此处是待分发的内容--> <p slot="header">header</p> <div slot="header">header1</div> <p slot="footer">footer</p> <p>default</p> </child></div><template id="child-template"> <div> <slot name="header" v-bind:header="'header'"></slot> <slot>默认分发处</slot> <slot name="footer" v-bind:footer="'footer'"></slot> </div></template>Console 输出
v2.5.22 屡次调用同一个具名插槽.png
v2.6.·0 屡次调用同一个具名插槽.png
从输出结果可以看出老式写法在v2.6.0以前和以后都能在$slots里有两个header的具名插槽内容,这与后面新式写法就有不同。
二、v-slot, v-slot:[name]=slotProps 和 $slots, $scopedSlots 的关系
1. 无作用域插槽
HTML
<div id="parent-template"> <child> <!--此处是待分发的内容--> <template v-slot:header> <p>{{ header }}</p> </template> <template v-slot:footer> <p>footer</p> </template> <template v-slot:default> <p>default</p> </template> </child></div><template id="child-template"> <div> <slot name="header"></slot> <slot>默认分发处</slot> <slot name="footer"></slot> </div></template>Console输出
v2.6.10 具名插槽.png
从输出可以看出,新式写法在v2.6.0版本后,default中tag 为 undfined的元素没有了,并且$slots中的内容是后面塞进去的,$scopedSlots一开始就有。
2. 有作用域插槽
HTML
<div id="parent-template"> <child> <!--此处是待分发的内容--> <template v-slot:header="{header}"> <p>{{ header }}</p> </template> <template v-slot:footer> <p>footer</p> </template> <template v-slot:default> <p>default</p> </template> </child></div><template id="child-template"> <div> <slot name="header" v-bind:header="'header'"></slot> <slot>默认分发处</slot> <slot name="footer" v-bind:header="'footer'"></slot> </div></template>Console 输出
v2.6.10 作用域插槽.png
这个输出同老式写法在v2.6.0版本后的输出一样,除了一开始$slots里面没有值,是后面塞进去的。
3. 屡次调用同一个具名插槽
HTML
<div id="parent-template"> <child> <!--此处是待分发的内容--> <template v-slot:header> <p>header</p> </template> <template v-slot:header> <p>header1</p> </template> <template v-slot:footer> <p>footer</p> </template> <template v-slot:default> <p>default</p> </template> </child></div><template id="child-template"> <div> <slot name="header" v-bind:header="'header'"></slot> <slot>默认分发处</slot> <slot name="footer" v-bind:header="'footer'"></slot> </div></template>Console输出
v2.6.10 屡次使用具名插槽
从输出可以看出,新式写法屡次调用同一个具名插槽,后面的会覆盖前面的,这个和老是写法一个比较大的区别,在更新的时候就要特别注意。
小结
经过上面的实践比照,有以下几点结论:
- v2.6.0以后在
$slots里可以取到具名key,在$scopedSlots都能取到; - v2.6.0以后
v-slot的写法不能屡次使用同名的具名插槽,后面的会覆盖前面的,不会显示两个同名具名插槽的内容; - v2.6.0以后用
v-slot的写法,假如在子组件中用$slot,肯定调用watch方法,由于一开始$slots为空,后面才塞入的数据。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Vue之深入了解插槽—slot, slot-scope, v-slot, v-slot:[name]=slotProps, $slots, $scopedSlots