前言:
前端项目的特点:
当前我们开发的前端项目都是以视图作为划分单位,将不同区域的视图显示划分成了许许多多的【碎片】。
组件化就是一种流行,高效,易维护的视图划分模式。
从组件化说起:
组件化 就是将视图划分成易维护 、可复用 、职责单一的视图碎片。
在项目中,这些碎片组成了我们项目需要的样子和功能,并最终组合成一个页面交互的整体(组件树)
在 Vue 组件的数据传递中,通常使用 props 这种标准化传递方式来进行数据传递。
模拟场景:
假定有一个这样的场景:
- 组件树上面有两个组件:组件 A、组件 B
- 组件 A 的可配置性很高,数据来源都是外界提供的
- 组件 B 的复用性很高,可以在任意组件之中渲染
从原则上来讲,组件 A 和组件 B 之间是可以相互依赖共用的。但是:
- 当组件树变得越来越复杂,它们需要嵌套和复用的次数越来越多(组合 & 嵌套),就会有可能产生许多层组件并未使用的数据出现的问题
- 当组件使用多次时,数据来源追踪困难
- 通常情况下,每次使用组件,都需要进行注册并且注册完成就要思考嵌套的数据来源
补充 - 组件设计的一些注意点:
- 组件依赖关系要简单
- 组件的嵌套不能太深(组件设计需要扁平化)
虽然 props 是组件数据传递的标准方式,但是上述的业务场景可能会导致标准的数据传递方式使用起来不太灵光!
这个时候,我们就需要使用 provide
& inject
(依赖注入) 的方式来解决我们在组件数据传递的标准方式不太使用的情景。
Provide & Inject
概述:
Provide
& Inject
是 Vue 官方提出的祖先组件派发数据给后代组件的非标准数据传递方式,具体步骤如下:
- 祖先组件使用 provide 提供数据(状态 & 方法)
- 后代组件调用 inject 接收组建组件传递的数据
代码示例:
基本使用
- 祖先定义
html
<template>
<Child />
</template>
<script>
import { defineComponent } from 'vue';
import Child from './Child.vue';
export default defineComponent({
name: 'Ancient',
components: {
Child
},
provide() {
return {
msg: 'hello my child'
};
}
});
</script>
- 后代获取
html
<template>
<div>
<h2>{{ msg }}</h2>
</div>
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Child',
inject: ['msg']
});
</script>
补充:定义响应式数据
- provide 和 inject 默认传递的数据不是响应式的 (不被代理 / 数据劫持)
- 在 Vue3 中,如果在 options API 需要传递响应式数据,需要使用 Vue.computed 包裹数据!
- 在 Vue2 中,只能传递响应式对象来维持数据的深度响应!
传递方法
- 祖先定义
html
<template>
<Child />
</template>
<script>
import { defineComponent } from 'vue';
import Child from './Child.vue';
export default defineComponent({
name: 'Ancient',
components: {
Child
},
provide() {
const { print } = this;
return {
msg: 'hello my child',
print
};
},
methods: {
print(msg) {
console.log(msg);
return this.print.bind(this);
}
},
});
</script>
- 后代获取
html
<template>
<div>
<h2 @click="print('hahaha')">{{ msg }}</h2>
</div>
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Child',
inject: ['msg', 'print']
});
</script>
总结 - 什么场景下适合使用 Provide & Inject 呢?
- 在一个组件体系 下,如果有深度嵌套
- 在一个组件体系 下,多层级多个组件使用的时候