vue 子元件為何不可以修改父元件傳遞的值?

GeekQiaQia發表於2019-04-03

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

<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>
複製程式碼

相關文章