vue中的provide可以進(jìn)行父組件向后代組件進(jìn)行傳值。但是,他沒(méi)辦法監(jiān)聽(tīng)傳輸數(shù)據(jù)的變化。或者說(shuō)明白點(diǎn),就是如果我在父組件改變注入的值,它沒(méi)辦法更新。子組件改變傳入的值,它也沒(méi)辦法進(jìn)行更新
vue官方說(shuō)明:https://cn.vuejs.org/v2/api/#provide-inject

在線測(cè)試地址:https://codesandbox.io/s/snowy-forest-zed14
我們經(jīng)過(guò)測(cè)試發(fā)現(xiàn):
// 父組件
provide: function() {
this.myData3 = Vue.observable({
val: "我沒(méi)改變",
});
return {
myData1: this.myData1, //非響應(yīng)
myData2: this.myData2, //響應(yīng)
myData3: this.myData3, //響應(yīng)
};
},
data() {
return {
myData1: "我沒(méi)改變",
myData2: {
val: "我沒(méi)改變",
},
};
},
methods: {
change(){
this.myData1 = "我改變了" // 觸發(fā)后不能改變
this.myData2.val = "我改變了" // 觸發(fā)后能改變
this.myData3.val = "我改變了" // 觸發(fā)后能改變
// 觸發(fā)后不能改變
this.myData2 = {
val: "我改變了",
}
// 觸發(fā)后不能改變
this.myData3 = {
val: "我改變了",
}
},
}
// 孫組件
inject: ["myData1", "myData2", "myData3"],
以上這幾種方式都無(wú)法響應(yīng)和對(duì)一整個(gè)對(duì)象賦值的改變,并且watch和computed也無(wú)法監(jiān)聽(tīng)到一整個(gè)對(duì)象賦值的改變,只能響應(yīng)和監(jiān)聽(tīng)某個(gè)對(duì)象中的屬性改變,這不符合我們的使用習(xí)慣,我們希望可以對(duì)一整個(gè)對(duì)象賦值并監(jiān)聽(tīng)它的改變
如果我們希望整個(gè)數(shù)據(jù)都是響應(yīng)式的。那么可以通過(guò)以下方法實(shí)現(xiàn):
我們可以讓provide提供一個(gè)函數(shù)。函數(shù)內(nèi)部返回一個(gè)響應(yīng)式的數(shù)據(jù)。此時(shí)整條數(shù)據(jù)的響應(yīng)式的狀態(tài)并不會(huì)丟失。
而且這樣做有一個(gè)好處,即無(wú)法直接修改myData4 的值,因?yàn)樗且粋€(gè)計(jì)算屬性。這樣就可以避免數(shù)據(jù)的混亂。
關(guān)鍵代碼如下:
// 父組件
provide: function () {
return {
myData4: () => this.myData4, //響應(yīng)
};
},
data() {
return {
myData4: {
val: "我沒(méi)改變",
},
};
},
methods: {
change() {
// 觸發(fā)后能改變
this.myData4 = {
val: "我改變了",
};
},
},
// 孫組件
inject: ["myData4"],
computed: {
computedMyData4() {
return this.myData4()
}
},
watch: {
computedMyData4(val) {
console.log("我是孫組件,我監(jiān)聽(tīng)到了myData4改變", val);
},
},