项目场景:
因为封装公司的el-table组件需要兼容无限嵌套表头,使用组件引用自身实现可无限嵌套,但是会导致作用域问题导致后代组件读取不到祖先组件的作用域插槽
问题描述
发现父组件传给子组件的作用域插槽在孙组件及后代组件读取不到
父组件.vue
<son>
<template #sonSlot="{ msg }">
<p style="color: red;">{{ msg }}</p>
</template>
<template #grandsonSlot="{ msg }">
<p style="color: green;">{{ msg }}</p>
</template>
</son>
<script>
import son from "./son .vue"
export default {
components: {
son
},
}
</script>
子组件.vue
<template>
<div class="son">
<h1>我是儿子组件</h1>
<slot name="sonSlot" v-bind="{ msg: '子传父' }">123</slot>
<grandson>
</grandson>
</div>
</template>
<script>
import grandson from "./grandson.vue"
export default {
components: {
grandson
},
}
</script>
孙组件.vue
<template>
<div class="grandson">
<h1>我是孙子组件
</h1>
<div>
<slot name="grandsonSlot" v-bind="{ msg: '孙传爷' }">456</slot>
</div>
</div>
</template>
运行
原因分析:
打印子组件和孙组件$scopedSlots看看 组件只能读取父组件传的作用域插槽
解决方案:
需要在子组件把父组件传过来的作用域插槽传给孙组件
修改后子组件.vue
<template>
<div class="son">
<h1>我是儿子组件</h1>
<slot name="sonSlot" v-bind="{ msg: '子传父' }">123</slot>
<grandson>
<template v-slot:[key]="{ msg }" v-for="(value, key) in $scopedSlots">
<slot :name="key" v-bind="{ msg }"></slot>
</template>
</grandson>
</div>
</template>
<script>
import grandson from "./grandson.vue"
export default {
components: {
grandson
},
}
</script>
运行
结论
通过传递作用域插槽可实现只需在祖先组件写作用域插槽,后代组件皆可使用。方便组件封装