一,基本用法
就是子组件提供一个坑,父组件想要填什么就通过<slot>往坑里填,插槽里面的内容会被覆盖 被父组件填了
或者这样理解:插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示、以及怎样显示由父组件来决定
<body>
<div id="app">
<com>随便填入点东西</com>
</div>
</body>
<script>
var com = {
template: `<div>
<h1>下面是插槽内容</h1>
<slot>杀杀杀</slot>
</div>`,
};
var vm = new Vue({
el: '#app',
components: {
com,
}
})
</script>
二,具名插槽
- 子组件<com>里面不管是啥都全往这个 这个坑里面填,肯定不好啊,无法区别哪个坑填什么
- 父组件为了能区别开来,可通过<slot>标签中的name属性来区分
- 通过name属性将父组件想填的值传递给对应的插槽(坑🕳) ,没有name属性就填到默认坑里
- 注意当想一个坑里面填入多个内容的时候 可以用一个标签包括最外面,但是这样就产生没用的DOM元素
- 所以用template标签 来替代 就不会产生多余的 最外一层包裹的标签,实现让多个标签插入到一个插槽里面
<div id="app">
<oo>
<!-- 根据slot的名字来向模板对象中插入 -->
<h2 slot="footer">底部信息</h2>
<h4>身体信息</h4>
<h4>身体信息2</h4>
<h4>身体信息4</h4>
<!-- <h1 slot="header">
<p>头部</p>
<p>头部二</p>
</h1> -->
<template slot="header">
<p>头部</p>
<p>头部二</p>
</template>
</oo>
</div>
</body>
<script type="text/javascript">
Vue.component("oo", {
template: `
<div>
<header><slot name="header"></slot></header>
<body><slot></slot></body>
<footer><slot name="footer"></slot></footer>
</div>
`
})
var vm = new Vue({
el: "#app",
})
</script>
随便一提:在 2.6.0 中版本的插槽已经舍去了slot="footer" 这种写法, 目前还支持,但是以及不被推荐 改为 v-slot
<template v-slot:footer>
<h1>底部信息</h1>
</template>
三,作用域插槽
用来作为父组件对子组件数据就行进行加工,很多时候希望子组件以不同的方式来渲染,父组件来获取子组件的数据,来按照需求用solt-scope属性对子组件的部分数据进行获取,再进行加工
<style>
.current {
color: hotpink;
}
</style>
<body>
<div id="app">
<oo>
<template slot-scope="slotProps">
<strong v-if="slotProps.info.id==2" class="current"> {{slotProps.info.name}}</strong>
<h2 v-else>{{slotProps.info.name}}</h2>
</template>
</oo>
</div>
</body>
<script>
Vue.component("oo", {
template: `
<div>
<li :key="item.id" v-for="item in arr">
<slot :info="item"></slot>
</li>
</div>
`,
data() {
return {
arr: [{
id: 1,
name: "aa"
}, {
id: 2,
name: "bb"
}, {
id: 3,
name: "cccc"
}],
}
}
})
var vm = new Vue({
el: "#app"
})
</script>
- 如果不加template 就是单纯的对显示子组件,加上这块内容来对子组件的内容加工后显示
- slot-scope对象的属性值是来获取子组件传递过来的数据,当然子组件的 :info="item' 就是给父组件提供数据
- 经过父组件的加工,将加工好的每条数据插入到插槽中 就实现了父组件对子组件数据的加工显示
- 同样 新版本用v-slot来替换了slot-scope,下面是新版本推荐的写法
<oo>
<template v-slot="slotProps">
<strong v-if="slotProps.info.id==2" class="current"> {{slotProps.info.name}}</strong>
<h2 v-else>{{slotProps.info.name}}</h2>
</template>
</oo>
注意区别: 在具名插槽中 是v-slot:footer 作用域插槽中是 v-slot="slotProps" 如果只想单纯将子组件显示在父组件上,内容可以由父组件确定,填到对应的坑中,那么具名插槽就行,如果相对子组件的数据进行加工,就要作用域插槽