文章目录


没有插槽的情况

<div id="app">
<child>
<span>1111</span>
</child>
</div>


<script>// 注册子组件
Vue.component("child", {
template: "<div>这是一个div标签</div>"
});

// 初始化父组件
new Vue({
el: "#app"
});</script>

模版里的 ​​span标签​​​ 会被替代成 “​​<div>这是一个div标签</div>​​” 如下图:

Vue之slot插槽和作用域插槽_作用域


Vue2.x 插槽

有插槽的情况

简单来说,使用 ​​slot标签​​​ ,可以将​​<span>1111</span>​​,放到子组件中想让他显示的地方。如下图:

<div id="app">
<child>
<span>1111</span>
</child>
</div>


<script>// 注册子组件
Vue.component("child", {
template: "<div>这是<slot></slot>一个div标签</div>"
});

// 初始化父组件
new Vue({
el: "#app"
});</script>

Vue之slot插槽和作用域插槽_vue_02

即使有多个标签,会一起被插入,相当于用父组件放在子组件里的标签,替换了​​<slot></slot>​​这个标签。如下图:

<div id="app">
<child>
<span>1111</span>
<i>2222</i>
<b>3333</b>
</child>
</div>


<script>// 注册子组件
Vue.component("child", {
template: "<div>这是<slot></slot>一个div标签</div>"
});

// 初始化父组件
new Vue({
el: "#app"
});</script>

Vue之slot插槽和作用域插槽_作用域插槽_03


具名插槽

  1. 父组件在要分发的标签里添加​​slot="xxx"​​ 属性
  2. 子组件在对应分发的位置的​​slot标签​​​ 里,添加​​name="xxx"​​ 属性
  3. 然后就会将对应的标签放在对应的位置了。如下图:
<div id="app">
<child>
<span slot="one">1111</span>
<i slot="two">2222</i>
<b slot="three">3333</b>
</child>
</div>


<script>// 注册子组件
Vue.component("child", {
template: `<div>
这是
<slot name='one'></slot>
一个
<slot name='two'></slot>
div
<slot name='three'></slot>
标签
</div>`
});


// 初始化父组件
new Vue({
el: "#app"
});</script>

Vue之slot插槽和作用域插槽_作用域_04


没有slot属性

如果子组件标签中没有slot属性,将会显示默认的值

<div id="app">
<child>
<!-- <span slot="one">1111</span> -->
<i slot="two">2222</i>
<!-- <b slot="three">3333</b> -->
</child>
</div>

<script>// 注册子组件
Vue.component("child", {
template: `<div>
<slot name='one'>no one</slot>
<slot name='two'>no two</slot>
<slot name='three'>no three</slot>
</div>`

});

// 初始化父组件
new Vue({
el: "#app"
});</script>

​slot="two"​​ 就被插到固定的位置上,如下图:

Vue之slot插槽和作用域插槽_插槽_05


插槽简单实例应用

想想你的电脑主板上的各种插槽,有插CPU的,有插显卡的,有插内存的,有插硬盘的,所以假设有个组件是computer,其模板是template ,如下:

<body>
<div id="app">
<computer>
<div slot="CPU">Intel Core i7</div>
<div slot="GPU">GTX980Ti</div>
<div slot="Memory">Kingston 32G</div>
<div slot="Hard-drive">Samsung SSD 1T</div>
</computer>
</div>

<script>// 注册子组件
Vue.component("computer", {
template: `<div>
<slot name="CPU">这儿插你的CPU</slot>
<slot name="GPU">这儿插你的显卡</slot>
<slot name="Memory">这儿插你的内存</slot>
<slot name="Hard-drive">这儿插你的硬盘</slot>
</div>`
});

// 初始化父组件
new Vue({
el: "#app"
});</script>
</body>

Vue之slot插槽和作用域插槽_作用域插槽_06


作用域插槽 ( 2.1.0 新增 )

作用域插槽是一种特殊类型的插槽,用作一个 (能被传递数据的) 可重用模板,来代替已经渲染好的元素。

  1. 在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样
  2. 在父组件中,通过​​slot-scope="scoped"​​​ 的形式,获取子组件传递过来的数据,该数据对象的别名为​​scoped​​。这就是作用域插槽的模板。
<div id="app">
<child>
<!-- 2. 接收myName数据,scoped 为 { "myName": "猫老板的豆" } -->
<template slot="content" slot-scope="scoped">
<div>{{ scoped.myName }}</div>
</template>
</child>
</div>

<script>.component('child', {
data () {
return {
myName: '猫老板的豆'
}
},
template: `<slot name="content" :myName="myName"></slot>` // 1. 对外抛出 myName 数据
})

new Vue({
el: "#app"
});</script>

Vue3.x 插槽

插槽

<!-- 父组件 -->
<template>
<Child>
<!-- Vue2.x写法
<div slot="parent">
<div>父组件</div>
</div>
-->
<template v-slot:parent>
<div>父组件</div>
</template>
</Child>
</template>


<!-- 子组件 -->
<template>
<slot name='parent'>子组件</slot>
</template>

作用域插槽

在 Vue2.x 中具名插槽和作用域插槽分别使用 ​​slot​​​ 和 ​​slot-scope​​​ 来实现, 在 Vue3.x 中将 ​​slot​​​ 和 ​​slot-scope​​进行了合并统一使用

父组件:

<template>
<Child>
<!-- <template slot="content" slot-scope="scoped"> -->
<template v-slot:content="scoped">
<div>{{scoped.myName}}</div>
</template>
</Child>
</template>

子组件:

<template>
<slot name="content" :myName="myName"></slot>
</template>

<script>import { ref } from 'vue'
export default {
setup () {

let myName = ref("猫老板的豆")

return { myName }
},
}</script>