vue实现分发
Vue 实现分发的方法
Vue 中实现分发主要通过插槽(Slots)和 provide/inject 机制完成,以下是具体实现方式:
插槽(Slots)
插槽是 Vue 中实现内容分发的核心机制,允许父组件向子组件传递模板内容。
默认插槽
子组件中定义 <slot> 标签作为内容占位符:
<!-- 子组件 Child.vue -->
<template>
<div>
<h2>子组件标题</h2>
<slot></slot>
</div>
</template>
父组件向插槽传递内容:
<!-- 父组件 Parent.vue -->
<template>
<Child>
<p>这是分发到子组件的内容</p>
</Child>
</template>
具名插槽
当需要多个插槽时,可以使用具名插槽:
<!-- 子组件 Layout.vue -->
<template>
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
父组件使用 v-slot 指令指定插槽名称:
<!-- 父组件 -->
<template>
<Layout>
<template v-slot:header>
<h1>页眉内容</h1>
</template>
<p>主要内容</p>
<template v-slot:footer>
<p>页脚内容</p>
</template>
</Layout>
</template>
作用域插槽
当需要让插槽内容访问子组件数据时:
<!-- 子组件 ScopedChild.vue -->
<template>
<div>
<slot :user="user"></slot>
</div>
</template>
<script>
export default {
data() {
return {
user: {
name: 'John',
age: 30
}
}
}
}
</script>
父组件接收作用域数据:
<!-- 父组件 -->
<template>
<ScopedChild>
<template v-slot:default="slotProps">
<p>用户名: {{ slotProps.user.name }}</p>
<p>年龄: {{ slotProps.user.age }}</p>
</template>
</ScopedChild>
</template>
provide/inject
对于深层嵌套组件间的数据分发,可以使用 provide/inject:
// 祖先组件
export default {
provide() {
return {
theme: 'dark'
}
}
}
// 后代组件
export default {
inject: ['theme'],
created() {
console.log(this.theme) // => 'dark'
}
}
动态组件
通过 <component> 标签实现动态分发:
<template>
<component :is="currentComponent"></component>
</template>
<script>
export default {
data() {
return {
currentComponent: 'ComponentA'
}
}
}
</script>
渲染函数
在渲染函数中直接控制分发逻辑:

export default {
render(h) {
return h('div', [
this.$slots.default,
this.$scopedSlots.header({ text: '标题' })
])
}
}
注意事项
- 插槽内容是在父组件作用域中编译的,只能访问父组件的数据
- 作用域插槽允许子组件向插槽传递数据
provide/inject主要用于插件/组件库开发,应用代码中应谨慎使用- 动态组件切换时,默认会销毁旧组件实例,可通过
<keep-alive>缓存






