第 40 题:在 Vue 中,子组件为何不可以修改父组件传递的 Prop,如果修改了,Vue 是如何监控到属性的修改并给出警告的
单向数据流,这样处理是为了易于监测数据的流动,出现了错误可以更加迅速的定位到错误发生的位置。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: 第 41 题:考察作用域的一道代码题
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
单向数据流,这样处理是为了易于监测数据的流动,出现了错误可以更加迅速的定位到错误发生的位置。
上一篇: 第 41 题:考察作用域的一道代码题
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(17)
为什么修改引用类型的数据不会触发提示呢,源码里似乎没看到对基本属性和引用类型的判断
因为set只能监听到值的修改,当值是一个对象时,监听不到对象的属性的修改。
那如果父级传入到子组件的不是一个引用而是一个copy的对象,是不是子组件就可以改呢? 这样是不是就不会影响到其他的子组件了呢?
我觉得props能不能改只是框架的自己的一种设计,当然它也给了不能修改的理由
为什么修改引用类型的数据不会触发提示呢,源码里没看到对基本属性和引用类型的判断
说子组件不可以修改父组件传递的props是不够严谨的,我们在用this[key]来修改props的时候,完全可以改变该组件的vm._props,只是父组件传递的数据源是不会改变的,保证了数据源的唯一性。
原因就是要看vue源码中对props初始化的函数iniProps上。
综上,也就是说我们在用 this[key] = newVal来改变组件中的props的时候,实际改变的是vm下边的_props, 而由父组件传来的propsOptions并没有发生改变,这里应该注意的是当this._props[key]是基础数据类型的时候,this._props[key] 就是 propsData[key] 的拷贝值,当this._props[key]为引用类型的时候,this._props[key] 和 propsData[key] 指向的是同一个栈内存,**也就是说我们修改this._props[key]下的属性时候, propsData[key]也发生了改变,也就是父元素的数据发生了改变
那么如果修改了,Vue是怎么监控的呢,就是要看defineReactive函数
props也是深度数据响应吧,用的同一个defineReactive方法来实现
vue数据传递是单项数据流,如果父组件传递过来的props为引用类型,直接修改了props的值会导致其他用到此props的子组件的值也发生改变,导致数据混乱,以及难以追踪的bug。如果props是基础类型,不会造成其他影响,但也会是整个组件数据混乱
原因很简单,一个父组件下不只有你一个子组件。
同样,使用这份 prop 数据的也不只有你一个子组件。
如果每个子组件都能修改 prop 的话,将会导致修改数据的源头不止一处。
所以我们需要将修改数据的源头统一为父组件,子组件像要改 prop 只能委托父组件帮它。从而保证数据修改源唯一
个人感觉 就从父组件底下有未知个子组件 如果子组件可以直接修改父组件的值 别的子组件也依赖父组件的这个值的话就乱了 ,不好追踪, 子组件通过$emit方式实际还是父组件修改好了再通过数据流传过来而已
这道题不错
然而 props传入的是对象的话 是可以直接在子组件里更改的, 因为是同一个引用
组件对于data的监听是深度监听
而对于props的监听是浅度监听
为何不能修改:为了保证数据的单向流动,便于对数据进行追踪,避免数据混乱。官网有详细的信息 prop
vue如何知道修改了父组件传来的props?
下面的代码就是实现Vue提示修改props的操作,在组件
initProps
方法的时候,会对props进行defineReactive操作,传入的第四个参数是自定义的set函数,该函数会在触发props的set方法时执行,当props修改了,就会运行这里传入的第四个参数,然后进行判断,如果不是root根组件,并且不是更新子组件,那么说明更新的是props,所以会警告如果传入的props是基本数据类型,子组件修改父组件传的props会警告,并且修改不成功,如果传入的是引用数据类型,那么修改改引用数据类型的某个属性值时,对应的props也会修改,并且vue不会抱警告。
我的博客
@LzOo0oO,怎么玩?来,come on!举个例子?
漂亮, 还可以这么玩!
貌似是 极客时间 里面 那个作者提出来的问题~ 不过楼主你真的很认真哟~
子组件为何不可以修改父组件传递的 Prop?-> 因为每当父组件属性值修改时,该值都将被覆盖;如果要有不同的改变,可以用基于prop的data或者computed
单向数据流,易于监测数据的流动,出现了错误可以更加迅速的定位到错误发生的位置。
在initProps的时候,在defineReactive时通过判断是否在开发环境,如果是开发环境,会在触发set的时候判断是否此key是否处于updatingChildren中被修改,如果不是,说明此修改来自子组件,触发warning提示。