插槽,也就是slot,是组件的一块HTML模板,一个slot最核心的两个问题是显示不显示和怎样显示
1、单个slot
单个插槽,别名默认插槽、匿名插槽,不用设置name属性
<div id="app"> <children1> <span>12345</span> </children1></div><script type="text/javascript"> var app = new Vue({ el: '#app', components: { children1: { template: "<button><slot></slot>单个插槽</button>" } } });</script>
2、具名slot
插槽加了name属性,就变成了具名插槽。具名插槽可以在一个组件中出现N次,出现在不同的位置
<div id="app"> <children2> <span slot="first" @click="tobeknow">12345</span> <span slot="second">56789</span> </children2></div><script type="text/javascript"> var app = new Vue({ el: '#app', methods: { tobeknow: function () { console.log("It is the parent's method"); } }, components: { children2: {//这个无返回值,不会继续派发 template: "<button><slot name='first'></slot>具名插槽,<slot name='second'></slot></button>" } } });</script>
3、作用域slot
vue2.5版本中slot-scope取代了scope,来实现作用域插槽,主要用在组件调用中,具体在template标签上面使用slot-scope来获取插槽slot上面的属性值,获取值的为一个对象,slot-scope=”它可以取任意字符串”,在element-ui的组件中经常看到。
<div id="app"> <!-- 将数据传递给组件 --> <tb-list :data="data"> <!-- 获取slot上面的值 --> <template slot-scope="scope"> <p>索引:{{JSON.stringify(scope)}}</p> <p>索引:{{scope.$index}}</p> <p>姓名:{{scope.row.name}}</p> <p>年龄: {{scope.row.age}}</p> <p>性别: {{scope.row.sex}}</p> </template> </tb-list></div><script type="text/javascript"> var app = new Vue({ el: '#app', data: { data: [{ name: 'kongzhi1', age: '29', sex: 'man' }] }, components: { // 作用域slot 'tb-list': { template: `<ul> <li v-for="(item, index) in data"> <slot :row="item" :$index="index"></slot> </li> </ul>`, // 获取值 props: ['data'] } } });</script>
完整代码示例
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Vue入门之slot</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script></head><body><div id="app"> <children1> <span>12345</span> </children1> <children2> <span slot="first" @click="tobeknow">12345</span> <span slot="second">56789</span> </children2> <!-- 将数据传递给组件 --> <tb-list :data="data"> <!-- 获取slot上面的值 --> <template slot-scope="scope"> <p>索引:{{JSON.stringify(scope)}}</p> <p>索引:{{scope.$index}}</p> <p>姓名:{{scope.row.name}}</p> <p>年龄: {{scope.row.age}}</p> <p>性别: {{scope.row.sex}}</p> </template> </tb-list></div><script type="text/javascript"> var app = new Vue({ el: '#app', data: { data: [{ name: 'kongzhi1', age: '29', sex: 'man' }] }, methods: { tobeknow: function () { console.log("It is the parent's method"); } }, components: { // 单个slot children1: { template: "<button><slot></slot>单个插槽</button>" }, // 具名slot children2: { template: "<button><slot name='first'></slot>具名插槽,<slot name='second'></slot></button>" }, // 作用域slot 'tb-list': { template: `<ul> <li v-for="(item, index) in data"> <slot :row="item" :$index="index"></slot> </li> </ul>`, // 获取值 props: ['data'] } } });</script></body></html>