写点什么

vue 为何不允许子组件修改父组件 prop 传值

作者:达摩
  • 2022-12-12
    陕西
  • 本文字数:996 字

    阅读完需:约 3 分钟

vue为何不允许子组件修改父组件prop传值

VUE 官方文档上有很明确的解释:

单向数据流,所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

所以如果破坏了单向数据流,当应用复杂时,debug 的成本会非常高!!


在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。

那如果修改了,vue 是如何监控到属性并给出警告的?

在 vue 底层,做了一个类似全局标记 Flag;它的实现原理,还是 Object.defineProperty()API;


proxy.js

const sharedPropertyDefinition = {  enumerable: true,  // 可枚举  configurable: true  // 是否可以被修改 被delete}; 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>
复制代码


发布于: 刚刚阅读数: 3
用户头像

达摩

关注

还未添加个人签名 2019-12-04 加入

还未添加个人简介

评论

发布
暂无评论
vue为何不允许子组件修改父组件prop传值_Vue_达摩_InfoQ写作社区