Vue组件:依赖注入provide和inject的使用
1、Prop 逐级透传问题
通常情况下,当我们需要从父组件向子组件传递数据时,会使用 props。想象一下这样的结构:有一些多层级嵌套的组件,形成了一棵巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。在这种情况下,如果仅使用 props 则必须将其沿着组件链逐级传递下去,这会非常麻烦:
注意,虽然这里的 <Footer> 组件可能根本不关心这些 props,但为了使 <DeepChild> 能访问到它们,仍然需要定义并向下传递。如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为“prop 逐级透传”,显然是我们希望尽量避免的情况。
2、provide 和 inject 的使用
provide 和 inject 可以帮助我们解决这一问题。一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。
provide() 函数:为组件后代提供数据。
inject() 函数:要注入上层组件提供的数据。
【实例1】使用依赖注入 provide 和 inject,实现多层级组件之间的数据传递。
(1)修改 App.vue 根组件文件,实现爷爷组件功能,并使用 provide 传递数据。
<template><fieldset><legend>爷爷组件</legend><!-- 第三步:使用组件 --><ParentComponent></ParentComponent></fieldset>
</template><script>
//第一步:引用组件
import ParentComponent from '@/components/ParentComponent.vue';export default {// 核心代码:使用 provide 传递数据provide: {blogName: '您好,欢迎访问 pan_junbiao的博客',blogUrl: 'https://blog.csdn.net/pan_junbiao'},//第二步:注册组件components: {ParentComponent}
}
</script>
(2)创建 ParentComponent.vue 父组件。
<template><fieldset><legend>父组件</legend><!-- 第三步:使用组件 --><ChildComponent></ChildComponent></fieldset>
</template><script>
//第一步:引用组件
import ChildComponent from '@/components/ChildComponent.vue'
export default {//第二步:注册组件components: {ChildComponent,}
}
</script>
(3)创建 ChildComponent.vue 子组件,并使用 inject 接收爷爷组件传递的数据。
<template><fieldset><legend>子组件</legend><h3>子组件接收到爷爷组件传递的数据:</h3><p>博客信息:{{ blogName }}</p><p>博客信息:{{ blogUrl }}</p></fieldset>
</template><script>
export default {// 核心代码:使用 inject 接收数据inject: ['blogName', 'blogUrl']
}
</script>
执行结果:
【实例2】provide 的数据来自 data 选项,而 inject 接收到的数据保存到 data 选项。
(1)修改 App.vue 根组件文件,实现爷爷组件功能,将 provide 的数据读取来自 data 选项。
<template><fieldset><legend>爷爷组件</legend><!-- 第三步:使用组件 --><ParentComponent></ParentComponent></fieldset>
</template><script>
//第一步:引用组件
import ParentComponent from '@/components/ParentComponent.vue';export default {data() {return {blogName: '您好,欢迎访问 pan_junbiao的博客',blogUrl: 'https://blog.csdn.net/pan_junbiao'}},// 核心代码:使用 provide 传递数据provide() {return {blogName: this.blogName,blogUrl: this.blogUrl}},//第二步:注册组件components: {ParentComponent}
}
</script>
(2)修改 ChildComponent.vue 子组件,将 inject 接收爷爷组件传递的数据保存到 data 选项。
<template><fieldset><legend>子组件</legend><h3>子组件接收到爷爷组件传递的数据:</h3><p>博客信息:{{ blogName2 }}</p><p>博客信息:{{ blogUrl2 }}</p></fieldset>
</template><script>
export default {// 核心代码:使用 inject 接收数据inject: ['blogName', 'blogUrl'],data() {return {blogName2: this.blogName,blogUrl2: this.blogUrl}}
}
</script>
执行结果: