【实践】vue中利用provide/inject向下级组件传递信息

306 阅读2分钟

vue中的组件数据传递一直是一个比较老生常谈的话题

在我的实际使用中,其实最为棘手的问题是组件的层级过多的时候,如何将一些关键的信息传递给下级组件,所谓的下级组件包括了子组件,子组件的子组件.....,依赖注入 可能是最为简洁轻量的一个做法

在vue的官网教程里面也详细的说明了依赖注入: provide 选项允许我们指定我们想要提供给后代组件的数据/方法。这个用法可以让我们在任意后代组件中访问父组件的数据/方法。

实际上,你可以把依赖注入看作一部分“大范围有效的 prop”,除了:

  1. 祖先组件不需要知道哪些后代组件使用它提供的属性
  2. 后代组件不需要知道被注入的属性来自哪里

一个简单的例子:

A.vue

<template>
    <div>I am source component, my name is {{myName}}</div>
    <child-b></child-b>
</template>
<script>
import ChildB from './B.vue'
export default {
    name: 'a-com',
    components: {
        ChildB
    },
    provide: {
        getSourceName: this.getSourceName
    }
    data() {
        return {
            myName: 'A component'   
        }
    },
    methods: {
        getSourceName () {
            return this.myName
        }
    }
}
</script>

B.vue

<template>
    <div style="padding: 10px">
        <div>I am childb</div>
        <div>the source element is {{getSourceName()}}</div>
        <child-c></child-c>
    </div>
</template>
<script>
import ChildC from './C.vue'
export default {
    name: 'childb',
    components: {
        ChildC
    }
    inject:['getSourceName'],
    data() {
        reuturn {
        }
    },
    methods: {
    }
}
</script>

C.vue

<template>
    <div style="padding: 10px">
        <div>I am childc</div>
        <div>the source element is {{getSourceName()}}</div>
    </div>
</template>
<script>
export default {
    name: 'childc',
    inject:['getSourceName'],
    data() {
        reuturn {
        }
    },
    methods: {
    }
}
</script>

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