Vue 插槽
插槽的概念: 插槽的关键字slot,默认情况下,组件中的模板会覆盖组件中的原始内容(即自定义标签对内部的内容会不显示),解决办法就是使用插槽。
组件的原始内容: 即在vue实例范围之内,因此可以调用实例的data和methods
插槽共分为3中:
插槽的结构:
匿名插槽:<slot></slot>
具名插槽:<slot name=top></slot>
作用域插槽:<slot title='标题' :num=count></slot>
1. 匿名插槽
匿名插槽的作用: 保留组件中的所有原始标签内容,这种插槽被称为匿名插槽
直接在组件中写上slot标签对,就可以在根元素中的引用的组件中间显示所写的内容
子组件没有插槽
<template> <div id="app"> <children> <span>子组件内部元素</span> </children> </div> </template> <script> export default { name: 'hello', components: { children: { template: '<div>这里是子组件</div>' } } } </script> <!--渲染结果--> <div id="app"> <div>这里是子组件</div> </div>
如果想让span显示那么此刻就应该使用slot
<template> <div id="app"> <children> <span>子组件内部元素</span> </children> </div> </template> <script> export default { name: 'hello', components: { children: { template: '<div><slot><p>默认效果</p></slot>这里是子组件</div>' } } } </script> <!--渲染结果--> <div id="app"> <span>子组件内部元素</span> "这里是子组件" </div>
2. 具名插槽
凡是具有name属性的slot标签,就被称为具名插槽即<slot name=top>(在子组件中写,写的位置不同,在引用该模板的页面中显示的位置也会不一样)。
作用:
1. 在组件的原始内容的某个标签中,添加slot=top属性,指明该标签所对应的插槽的名称
2. 在组件模板中通过调用slot标签,兵设置name=top属性,会自动将对应的标签内容添加至当前slot标签所在的位置
<template> <div id="app"> <children> <div slot="header"> <ul> <li>首页</li> <li>商城</li> </ul> </div> <div> 这个是默认的没有具名的solt </div> <div slot="footer"> <p>备案号</p> </div> </children> </div> </template> <script> var Child = { template: ' <div>这是子组件<div></div> <slot name="header"></slot> <slot></slot> <slot name="footer"></slot> </div>' } export default { name: 'hello', components: { children: Child } } </script> <!--渲染结果为--> <div id="app"> <div> "这是子组件" <div></div> <div> <ul> <li>首页</li> <li>商城</li> </ul> </div> <div> "这个是默认没有具名的slot" </div> <div> <p>备案号</p> </div> </div> </div>
注意:原始内容凡是具有slot属性的标签,内容只能添加至组件模板中具有相同值的name属性的slot标签中
匿名插槽的作用: 保留了原始数据,除了具名插槽标签中的内容,即凡是标签中具有slot=top的属性标签
3. 作用域插槽
在组件的原始内容中,通过slot-scope属性接受作用域插槽传递的值,即obj={title:‘标题’,num:19}
作用域插槽:将组件模板中的数据传递给组件的原始内容
1. 在slot开始标签中,添加要传递的数据,避开name属性(具名插槽)
2. 在原始内容中通过slot-scope属性(其值是自定义的)接受传递的数据,即slot-scope=varName(本质是个对象,存储传递的数据,即数据会自动转换成键值对,存储在这个对象里,所以属性名对应属性名,属性值对应属性值)
<div id="app"> <child :lists="nameList"> <template slot-scope="a"> {{a}} </template> </child> </div> <script> Vue.component('child',{ props:['lists'], template:` <div> <ul> <li v-for="list in lists"> <slot :bbbbb="list"></slot> </li> </ul> `</div> }) let vm = new Vue({ el:'#app', data:{ nameList:[ {id:1,name:'张三'}, {id:2,name:'李四'}, {id:3,name:'王五'}, {id:4,name:'赵六'} ] } }) </script>