一. 问题
父组件:
export default {
provide() {
return { aaa: this.wordA}
},
data(){
return {
wordA: 'old word'
}
}
created() {
setTimeout(()=>{
this.wordA= "new words";
},1000)
},
}
子组件:
export default {
inject:['aaa'],
data(){
return {
childaaaOld: this.aaa
}
},
computed:{
childaaa() {
return this.aaa
}
},
created () {
console.log(this.aaa)
setTimeout(() => {
console.log(this.childaaa);
}, 2000);
}
}
上述代码会发现,父组件组件的aaa的值改变了,下级组件的childaaa的值不会跟着改变的,但实际使用的时候希望父组件的属性修改后,子组件能监听到属性的修改并执行一些逻辑。
二. 解决:
1. 将一个函数赋值给provide的一个值,这个函数返回父组件的动态数据,然后在子孙组件里面调用这个函数。实际上这个函数存储了父组件实例的引用,这样每次子组件都能获取到最新的数据
如下:
父组件:
<template>
<div class="parent-container">
<br/>
<button type="button" @click="changeName">改变name</button>
<br/>
<Child />
</div>
</template>
<script>
import Child from './Child'
export default {
name: 'Parent',
components: {
Child
}
data () {
return {
name: 'yuh'
}
},
methods: {
changeName (val) {
this.name = 'yu'
}
},
provide: function () {
return {
nameFromParent: this.name,
getReaciveNameFromParent: () => this.name
}
},
}
</script>
<style scoped>
.parent-container {
padding: 30px;
border: 1px solid burlywood;
}
</style>
子组件:
<template>
<div class="child-container">
<br/>
<GrandSon />
</div>
</template>
<script>
import GrandSon from './GrandSon'
export default {
components: {
GrandSon
}
}
</script>
<style scoped>
.child-container {
padding: 30px;
border: 1px solid burlywood;
}
</style>
孙组件:
<template>
<div class="grandson-container">
<br/>
{{nameFromParent}}
<br/>
{{reactiveNameFromParent}}
</div>
</template>
<script>
export default {
inject: ['nameFromParent', 'getReaciveNameFromParent'],
computed: {
reactiveNameFromParent () {
return this.getReaciveNameFromParent()
}
},
watch: {
'reactiveNameFromParent': function (val) {
console.log('来自Parent组件的name值发生了变化', val)
}
},
mounted () {
console.log(this.nameFromParent, 'nameFromParent')
}
}
</script>
<style scoped>
.grandson-container {
padding: 30px;
border: 1px solid burlywood;
}
</style>
这样就实现了孙组件中reactiveNameFromParent的值随着父组件中name的值变化而变化了
2. 我们也可以给provide的属性传入一个可监听的"对象",那么对象的属也性是可响应的。如下:
父组件:
export default {
provide(){
return {aaa: this.bbb}
},
data(){
return {
bbb:{a:'old word'}
}
}
created() {
setTimeout(()=>{
this.fonnB.a="new words";
},1000)
},
}
子组件:
export default {
inject:['aaa'],
data(){
return {
childaaaOld:this.aaa.a
}
},
computed:{
childaaa(){
return this.aaa.a
}
}
}