1

何为 provide/inject

provide/inject 是 Vue 在 2.2.0 版本新增的 API,官网介绍如下:

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。

使用 provide/inject 做全局状态管理

在官网文档中关于 provide/inject 有这么一个提示:

提示:provideinject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

也就是说,Vue 不会对 provide 中的变量进行响应式处理。所以,要想 inject 接受的变量是响应式的,provide 提供的变量本身就需要是响应式的。

由于组件内部的各种状态就是可响应的,所以我们直接在根组件中将组件本身注入 provide,此时,我们可以在后代组件中任意访问根组件中的所有状态,根组件就成为了全局状态的容器,仔细想想,是不是很像 React 中的 context 呢?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>provide/inject实现状态管理</title>
  <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
</head>
<body>
  <div id="app"></div>
</body>
</html>

<script>
  Vue.component('A', {
    template: `
      <div>
        <p><label>name: </label><span>{{ data.name }}</span></p>
        <p><label>age: </label><span>{{ data.age }}</span></p>
        <B></B>
        <C></C>
      </div>
    `,
    data() {
      return {
        data: {
          name: '',
          age: ''
        }
      }
    },
    provide() {
      return {
        // 因为data属性是响应式的(vue2使用Object.defineProperty/vue3使用proxy)
        data: this.data
      }
    }
  })
  Vue.component('B', {
    template: `
      <div>
        <button @click="changeName">changeName</button>
      </div>
    `,
    inject: ['data'],
    methods: {
      changeName() {
        this.data.name = 'tom'
      }
    }
  })
  Vue.component('C', {
    template: `
      <div>
        <button @click="changeAge">changeAge</button>
      </div>
    `,
    inject: ['data'],
    methods: {
      changeAge() {
        this.data.age = 20
      }
    }
  })
  var app=new Vue({
    el: '#app',
    template: `
      <div>
        <A />
      </div>
    `
  });
</script>

vuex状态可以分模块管理,provide/inject也可以实现,使用根组件包裹每一个模块,每个模块的根组件管理该模块的状态。

provide/inject实现状态管理与vuex区别

既然 provide/inject 如此好用,那么,为什么 Vue 官方还要推荐我们使用 Vuex,而不是用原生的 API 呢?

Vuex 和 provide/inject 最大的区别在于,Vuex 中的全局状态的每次修改是可以追踪回溯的,而 provide/inject 中变量的修改是无法控制的,换句话说,你不知道是哪个组件修改了这个全局状态。

参考:
https://juejin.im/post/5dc4cb...


记得要微笑
1.9k 声望4.5k 粉丝

知不足而奋进,望远山而前行,卯足劲,不减热爱。


引用和评论

0 条评论