1.首先,什么是slot?
slot在vue里叫内容分发(也叫插槽),它写在子组件中,它作用域在父组件上的(作用域在父组件上很重要).
2.slot的用法(代码演示)
1.单个slot
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<div id="app">
<child-component>这是分发的内容</child-component>
<child-component>这是更多分发的内容</child-component>
</div>
<script src="https://lib.baomitu.com/vue/2.6.10/vue.js"></script>
<script>
Vue.component('child-component', {
template: `
<div>
<slot>
<p>如果父组件没有内容,我将会出现;如果父组件有内容,我则消失</p>
</slot>
</div>
`
})
let app = new Vue({
el: '#app'
})
</script>
</body>
</html>
默认效果:
但如果父组件的内容删掉,则显示子组件的内容,效果如下:
上述总结:在子组件内使用特殊的slot元素就可以为这个子组件开启一个slot(也叫插槽),在父组件模板里,插入在子组件标签内的所有内容(即上述第一种情况里的p和分发内容+更多分发内容这些内容)将替代子组件的slot标签以及它的内容.下面是实战图示总结.
2.带name属性的slot(也叫具名slot)
写法规则:父组件里用slot属性关联子组件里的name属性;父组件里写内容,子组件里搭标签.
上述解释:子组件内声明了三个slot,其中只有main类里的slot(一个就好,多个会重复显示)没有使用name属性,它将作为默认slot出现,父组件没有使用slot属性的元素内容都将在这里显示.
3.作用域插槽slot(这是一个特殊的slot)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<my-list :books="books">
<!-- 作用域插槽可以是具名的插槽下面就是用了具名的slot;下面的props相当于v-for里的item一样,下面的template可以改成div,但必须配合slot-scope(vue2.5开始已经更新) -->
<template slot="book" slot-scope='props'>
<li>{{props.bookName}}</li>
</template>
</my-list>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
Vue.component('my-list',{
template:
`
<ul>
<slot
name='book'
v-for='book in books'
:book-name=book.name
>
</slot>
</ul>
`
,
props:{
books:{
type:Array,
default(){
return []
}
}
}
})
let app=new Vue({
el:"#app",
data() {
return {
books:[
{
name:'vue实战'
},
{
name:'js语言精髓'
},
{
name:'js高级程序设计'
}
]
}
},
})
</script>
</body>
</html>
上面的效果:
说明:子组件my-list接收来自父组件的数组books,并且将它在name为book的slot上使用v-for循环,同时暴露一个变量bookName.
问题:为什么不直接在父组件中使用v-for循环直接生成数据,而要这么麻烦呢?
未完待续