Vue组件通信:provide与inject

Vue.js 中,provideinject 是一种用于跨层级组件通信的机制,允许父组件向深层嵌套的子组件传递数据,而不需要通过 props 逐层传递。

使用方式

  1. 基础数据
// Parent
export default {
  provide: {
    word: "word",
    obj: {
      name: 'Parent'
    },
    arr: [1, 2, 3],
  }
}

// Children
export default {
  inject: ['word', 'obj', 'arr'],
  data() {
    return {
      word: this.word
    }
  }
}

provide 导出的数据为非响应式数据时,我们可以直接使用provide:{...}的对象形式来向子孙组件导出我们的数据,且这个数据在被修改后无法更新渲染视图。

  1. 响应式数据
// Parent
export default {
  data() {
    return {
      word: "Parent",
      obj: {
        name: 'Parent'
      },
      arr: [1, 2, 3]
    }
  },
  provide() {
    return {
      word: this.word,
      obj: this.obj,
      arr: this.arr
    }
  }
}

// Children
export default {
  inject: ['word', 'obj', 'arr'],
  data() {
    return {
      word: this.word,
      ...
    }
  }
}

provide 导出的数据为响应式数据时,我们可以直接使用provide(){return{...}}的函数形式来向子孙组件导出我们的数据。
此时我们会发现比较坑的一个点就是我明明导出的是响应式数据,为什么在数据更新后,子组件并没有同步渲染更新。
经过试验我们发现当导出响应式数据时可分为几种情况:

  1. 响应式数据为基本类型
    当为基本类型时,无论怎么修改父组件的data数据,子组件都不会更新。
  2. 响应式数据为对象
    当为对象类型时,直接赋值运算修改父组件的data数据,子组件不会更新,而修改对象属性,则子组件的视图会被更新。
  3. 响应式数据为数组
    当为数组类型时,直接赋值运算修改父组件的data数据,子组件不会更新,而在v3版本中通过push等操作修改时,子组件会被更新。
export default {
  data() {
    return {
      word: "Parent",
      obj: {
        name: 'Parent'
      },
      arr: [1, 2, 3]
    }
  },
  provide() {
    return {
      word: this.word,
      obj: this.obj,
      arr: this.arr
    }
  },
  mounted() {
    setTimeout(() => {
      // 子组件更新数据
      this.obj.name = 'ParentProvide'
      this.arr.push(4)

      // 子组件不更新数据
      this.obj = {
        name: 'ParentProvide'
      }
      this.arr = [4, 5, 6]
    }, 5000);
  }
}

在组合式API中 通过ref reactive声明的响应式数据则可以通过一下方式进行更新子组件

const word = ref('Parent');
provide('word', word);
const obj = reactive({ name: 'Parent' });
provide('obj', obj);
const arr = ref([1, 2, 3]);
provide('arr', arr);
setTimeout(() => {
  word.value = 'ParentProvide';
  obj.name = 'ParentProvide';
  arr.value = [1, 2, 3, 4];
}, 5000);

因为ref声明基本类型的响应式数据时,将基本类型转化为响应式对象,所以在通过xx.value 修改时,子组件会更新视图。
reactive 声明的响应式数据,由于整个对象为响应式的,则通过修改属性值,也可以实现子组件的更新。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容