[vue]依赖注入详解(vue2和vue3)优势和劣势

283 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

解释

  • 当一个module拥有超过两层的组件时,从后代组件一层层emit出去调用祖先组件的方法或一层层将祖先的数据用props传递到后代组件实在是太麻烦,当需要修改时也需要一层层去找需要修改的地方
  • provideinject是 提供与注入的意思,在这里我想到了nest里面service层作为provide注入到controller层,我觉得他们都使用了同一种设计模式,即 依赖-注入

复习

  • 父传子:props
  • 子传父:$emit
  • 父获取或调用子的数据或方法:this.$ref['child']this.$children
  • 子获取父组件的属性或方法:this.$parents

vue2

父组件

export default Vue.extend({
  name: "App",
  components: {
    HelloWorld,
    HelloWw,
  },
  data() {
    return {
      a: 0,
      b: 0,
    };
  },
  provide:{
    c: 'fujinting'
  },
 }

子组件或者孙组件或者重孙组件(后代组件)

<template>
    <div>
        ------------{{c}}----------
    </div>
</template>
<script>
export default {
    data() {
        return {

        }
    },
    inject:['c'],
    methods:{
        
    }
}
</script>

#vue3 父组件

<template>
  <div id="container">
      <h1>父组件 {{money}}</h1>
      <button @click="money = 1000">发钱</button>
      <hr>
      <Sonn />
  </div>
</template>
<script>
import Sonn from './Soon.vue'
import { provide,ref } from 'vue'
export default {
  name: "App",
  components: {
     Sonn  
  },
  setup() {
    const money = ref(100);
    const changeMoney = (saleMoney) => {
        console.log('changeMoney',saleMoney)
        money.value = money.value - saleMoney
    }
    // 将数据提供给后代组件 provide
    provide('money',money)
    // 将函数提供给后代组件 provide
    provide('changeMoney',changeMoney)
    return { money };
  },
};
</script>
<style lang='less' scoped>
</style>

子组件及后代组件

<template>
  <div id="container">
    <h3>子组件 {{money}}</h3>
    <hr />
    <GrandSon />
  </div>
</template>
<script>
import { inject } from 'vue';
import GrandSon from "./GrandSon.vue";
export default {
  name: "Sonn",
  components: {
    GrandSon,
  },
  setup(props) {
      // 接收祖先组件提供的数据
      const money = inject('money')
      // 不能在后代组件修改祖先组件传过来的值  -- 单向数据流
      // 数据遵循,谁定义,谁修改
      return { money }
  }
};
</script>
<style lang='less' scoped>
</style>

vue官方提醒:

然而,依赖注入还是有负面影响的。它将你应用程序中的组件与它们当前的组织方式耦合起来,使重构变得更加困难。同时所提供的 property 是非响应式的。这是出于设计的考虑,因为使用它们来创建一个中心化规模化的数据跟使用 $root做这件事都是不够好的。如果你想要共享的这个 property 是你的应用特有的,而不是通用化的,或者如果你想在祖先组件中更新所提供的数据,那么这意味着你可能需要换用一个像 Vuex 这样真正的状态管理方案了。

vue依赖注入的一些原则

不是响应式数据,是不能驱动试图的
不能在后代组件修改祖先组件传过来的值 – 单向数据流
数据遵循,谁定义,谁修改