对于组件树结构,底层叶子节点想获取根节点属性,并且要实现响应式,困难重重。
以前的做法都是通过vuex、$eventBus、props 逐级传递来实现组件响应式通信,显得过于繁琐。
不妨试试 provide、inject 依赖注入,方便又快捷。
原理图如下:
功能介绍:
provide:祖先节点(root)想要被访问的数据声明
inject:注入祖先节点声明的数据
代码展示
- 祖先节点(root)
computed声明,实现响应式数据变更
<template>
<Footer />
<button @click="setX()">setX</button>
</template>
<script>
import Footer from './Footer.vue'
import { computed } from 'vue'
export default {
components: { Footer },
provide() {
return {
all: computed(() => this)
}
},
data() {
return { x: 1 }
},
methods:{
setX(){
this.x=2
}
}
}
</script>
- 不用
computed函数也行,可以直接自定义方法实现
provide() {
return { all: this }
},
computed: {
provideX() { return this.x }
}
- Footer 中间节点
<template>
<DeepChild />
</template>
<script>
import DeepChild from './DeepChild.vue'
export default {
components: {
DeepChild
}
}
</script>
DeepChild 叶子节点,通过 inject 注入 root 节点声明的 all 属性
<template>
<div>{{ all.x }}</div>
</template>
<script>
export default {
inject: ['all']
}
</script>
运行以上代码,DeepChild 叶子节点可以直接获取 root 根节点的 x 数据并展示,当点击 setX 按钮,DeepChild 叶子节点,展示的数据也会随之变化
至此以上运行结果满足了响应式数据变更和组件间数据传递
应用场景:
嵌套极深的子组件需要祖先组件的数据
多个子组件需要共享同一个状态,可以同 provide 响应式数据变更,可以快速让各个子组件共享状态