别再用 props 传参了!不妨试试 Provide 依赖注入实现响应式数据变更

1,218 阅读1分钟

对于组件树结构,底层叶子节点想获取根节点属性,并且要实现响应式,困难重重。

以前的做法都是通过vuex$eventBusprops 逐级传递来实现组件响应式通信,显得过于繁琐。

不妨试试 provideinject 依赖注入,方便又快捷。

原理图如下:

provide-inject.C0gAIfVn.png

功能介绍:

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 响应式数据变更,可以快速让各个子组件共享状态