维埃斯。改变子组件中的 prop 不会触发警告。想知道为什么

Fra*_*ois 5 javascript vue.js vuejs2 vue-props

我注意到 prop 突变(Vue 2.6)有一些奇怪的地方。

应避免直接在子组件中改变 props,否则会触发以下著名的警告

“避免直接改变道具,因为该值将被覆盖......”

因此,如果在我的父组件中我有一个类似的数据

exemple: "Hello World"
Run Code Online (Sandbox Code Playgroud)

我将其作为道具传递给子组件。如果在那个子组件中我做了类似的事情

this.exemple = "Hello World!"
Run Code Online (Sandbox Code Playgroud)

我收到警告。很公平。现在我注意到,如果父级中的数据是像这样的对象

exemple : {message : "Hello World"}
Run Code Online (Sandbox Code Playgroud)

我在孩子身上做了类似的事情

this.exemple.message = "Hello World!"
Run Code Online (Sandbox Code Playgroud)

这不会触发任何警告,而且父组件中的数据会更新

我想知道为什么。为什么在一种情况下 prop 突变会传播到亲本,而在另一种情况下则不会?它可能与 javascript 如何存储这些变量有关吗?使用这个技巧是个好习惯吗?

Dan*_*Dan 4

为什么在一种情况下 prop 突变会传播到父代,而在另一种情况下却不会?它可能与 javascript 如何存储这些变量有关吗?

是的。当您改变JavaScript引用变量(例如对象和数组)的属性/值时,它们的引用不会更改。这意味着父级也可以访问更改的属性,因为它也可以访问引用。如果引用发生变化,Vue 只会给出 prop 突变警告。

警告:

this.prop = {}
Run Code Online (Sandbox Code Playgroud)

无警告:

this.prop.id = 5
Run Code Online (Sandbox Code Playgroud)

使用这个技巧是个好习惯吗?

不。这又回到了违反单向数据流的情况,其中数据通过 props 向下传递(到子级),并通过事件向上传递(到父级)。


好的,但是为什么 Vue 不警告这些变化呢?

考虑一个具有 1000 个属性的对象或一个具有 1000 个项目的数组。Vue 必须深入检查所有 1000 个更改,并且没有快速的方法来做到这一点,因为每个项目都必须单独与旧值进行比较。这会对性能产生影响,并可能导致许多应用程序无法使用。


以下是Vue 团队成员Bolerodan对此主题的评论

一般来说你不应该这样做。这可能会导致代码中出现意外的错误。一般来说,您应该复制对象,对其进行修改,然后向上发送给父对象(我相信正如您在上一段中提到的那样)。这是我采取的方法,也是自上而下、向上发射的普遍共识。