![4b64df7551c836423e845a2e68e05c89.png](https://img-blog.csdnimg.cn/img_convert/4b64df7551c836423e845a2e68e05c89.png)
有时候,我们需要让插槽内容访问子组件的数据。但是,我们知道插槽并不能访问到子组件的作用域,也就拿不到子组件中的数据。
欣欣:复习之Vue组件的插槽zhuanlan.zhihu.com![92b0c9c36374f7355a747281b43eaf56.png](https://img-blog.csdnimg.cn/img_convert/92b0c9c36374f7355a747281b43eaf56.png)
那么当我们想要拿到子组件的数据的时候,我们就需要使用Vue组件作用域插槽来获取子组件的数据了。
作用域插槽的使用方法
为了能够让插槽内容访问子组件的数据,我们可以将子组件的数据作为``<slot>``元素的一个特性绑定上去。
绑定在 ``<slot>`` 元素上的特性被称为**插槽 prop**。在父级作用域中,我们可以给``v-slot``带一个值来定义我们提供的插槽prop的名字。
如:
<div id="app">
<a-cmp>
<template v-slot:default='items'> //items 是 组件list数据的名字
<li> {{ items.item }} </li>
</template>
</a-cmp>
</div>
<script>
const vm = new Vue({
el: '#app',
components: {
'a-cmp': {
data() {
return {
list: [1, 2, 3, 4, 5]
}
},
template: `
<div>
<ul>
<slot
v-for="item in list"
:item="item"
></slot>
</ul>
</div>
`,
}
}
})
</script>
![eeb310a24940bbd1404f91083657119a.png](https://img-blog.csdnimg.cn/img_convert/eeb310a24940bbd1404f91083657119a.png)
独占作用域默认插槽的缩写语法
当被提供的内容只有默认插槽时,组件的标签可以被当作插槽的模板来使用。如:
<div id="app">
<a-cmp v-slot:default='items'>
<li> {{ items.item }} </li>
</a-cmp>
</div>
<script>
const vm = new Vue({
el: '#app',
components: {
'a-cmp': {
data() {
return {
list: [1, 2, 3, 4, 5]
}
},
template: `
<div>
<ul>
<slot
v-for="item in list"
:item="item"
></slot>
</ul>
</div>
`,
}
}
})
</script>
![37a69f874d6229d6a2d8f89ae719d2f9.png](https://img-blog.csdnimg.cn/img_convert/37a69f874d6229d6a2d8f89ae719d2f9.png)
也可以更简单,如:
<div id="app">
<a-cmp v-slot='items'>
<li> {{ items.item }} </li>
</a-cmp>
</div>
<script>
const vm = new Vue({
el: '#app',
components: {
'a-cmp': {
data() {
return {
list: [1, 2, 3, 4, 5]
}
},
template: `
<div>
<ul>
<slot
v-for="item in list"
:item="item"
></slot>
</ul>
</div>
`,
}
}
})
</script>
![37a69f874d6229d6a2d8f89ae719d2f9.png](https://img-blog.csdnimg.cn/img_convert/37a69f874d6229d6a2d8f89ae719d2f9.png)
注意:默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确。只要出现多个插槽,就需要为所有的插槽使用完整的基于``<template>``的语法。
解构作用域插槽Prop
我们可以使用解构传入具体的插槽prop,这样模板会更简洁,尤其是在为插槽提供了多个prop时。如:
<div id="app">
<a-cmp v-slot='{ item }'>
<li> {{ item }} </li>
</a-cmp>
</div>
<script>
const vm = new Vue({
el: '#app',
components: {
'a-cmp': {
data() {
return {
list: [1, 2, 3, 4, 5]
}
},
template: `
<div>
<ul>
<slot
v-for="item in list"
:item="item"
></slot>
</ul>
</div>
`,
}
}
})
</script>
![37a69f874d6229d6a2d8f89ae719d2f9.png](https://img-blog.csdnimg.cn/img_convert/37a69f874d6229d6a2d8f89ae719d2f9.png)
还可以给prop重命名,如:
<div id="app">
<a-cmp v-slot='{ item: count }'>
<li> {{ count }} </li>
</a-cmp>
</div>
<script>
const vm = new Vue({
el: '#app',
components: {
'a-cmp': {
data() {
return {
list: [1, 2, 3, 4, 5]
}
},
template: `
<div>
<ul>
<slot
v-for="item in list"
:item="item"
></slot>
</ul>
</div>
`,
}
}
})
</script>
以及自定义后备内容,当插槽prop是undefined时生效,如:
<div id="app">
<a-cmp v-slot='{ item = { name: "li" } }'>
<li> {{ item }} </li>
</a-cmp>
</div>
<script>
const vm = new Vue({
el: '#app',
components: {
'a-cmp': {
data() {
return {
list: undefined
}
},
template: `
<div>
<ul>
<slot
:item="list"
></slot>
</ul>
</div>
`,
}
}
})
</script>
![9f83761968aa46b781450146bf44a7d4.png](https://img-blog.csdnimg.cn/img_convert/9f83761968aa46b781450146bf44a7d4.png)