1、vue 子元件為何不可以修改父元件傳遞的值?
因為vue設計是單向資料流,資料的流動方向只能是自上往下的方向;
複製程式碼
2、如果修改了,vue 是如何監控到屬性並給出警告的?
在vue 底層,做了一個類似全域性標記Flag;它的實現原理,還是Object.defineProperty()API;引用在極客時間唐老師的一段程式碼,以下是老師做的粗略精簡程式碼模組:
proxy.js
const sharedPropertyDefinition = {
enumerable: true,
configurable: true
};
export default function proxy(target, temp, key) {
sharedPropertyDefinition.get = function proxyGetter() {
return temp[key];
};
sharedPropertyDefinition.set = function proxySetter(val) {
temp[key] = val;
if (!window.isUpdatingChildComponent) {
console.error(`不可以直接更改: ${key}`);
}
window.isUpdatingChildComponent = false;
};
Object.defineProperty(target, key, sharedPropertyDefinition);
複製程式碼
window.isUpdatingChildComponent = false; 相當於一個Flag;只有當在父元件中修改傳遞給子元件的Prop值的時候,才會被賦值為True; 在子元件Proxy.vue 中代理父元件傳遞的Prop值; 使用 this.$forceUpdate(); 強制更新; 這時候,觸發代理中的setter;提示不可以在子元件中直接修改父元件傳遞的Prop值的警告;
Proxy.vue
info: {{ info }}
<template>
<div>
info: {{ info }}
<input :value="info.name" @input="handleChange" />
</div>
</template>
<script>
import proxy from "./proxy";
export default {
props: {
info: Object
},
created() {
this.temp = { name: "" };
Object.keys(this.temp).forEach(key => {
proxy(this.info, this.temp, key);
});
},
methods: {
handleChange(e) {
this.info.name = e.target.value;
this.$forceUpdate();
//this.$emit("change", e.target.value);
}
}
};
</script>
複製程式碼