本文已参与「新人创作礼」活动,一起开启掘金创作之路。
解释
- 当一个module拥有
超过两层的组件时,从后代组件一层层emit出去调用祖先组件的方法或一层层将祖先的数据用props传递到后代组件实在是太麻烦,当需要修改时也需要一层层去找需要修改的地方provide和inject是 提供与注入的意思,在这里我想到了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依赖注入的一些原则
不是响应式数据,是不能驱动试图的
不能在后代组件修改祖先组件传过来的值 – 单向数据流
数据遵循,谁定义,谁修改