Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 避免直接改变道具。。。然而,这似乎就是官方的例子所做的吗?_Javascript_Vue.js_Vuejs2 - Fatal编程技术网

Javascript 避免直接改变道具。。。然而,这似乎就是官方的例子所做的吗?

Javascript 避免直接改变道具。。。然而,这似乎就是官方的例子所做的吗?,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,我正在编写一个递归树渲染器,并遭受这个“避免直接改变道具”的警告 据我理解,“道具放下,事件升起”意味着孩子不能/不应该直接更改家长数据。我可以通过编写大量代码来避免这个错误,其中一个组件$emit进行更改,其父组件捕获并重新发送该更改,然后一直到顶层组件,该组件最终可以更改数据,然后通过树向下渲染。虽然我得到了一个通用组件需要与其父组件无关的用例,但对于递归组件来说,它似乎效率极低 我注意到提供了官方的VueJs 2。但是查看该代码可以看出,子组件被传递了一个属于父组件的对象,但是子组件可以直

我正在编写一个递归树渲染器,并遭受这个“避免直接改变道具”的警告

据我理解,“道具放下,事件升起”意味着孩子不能/不应该直接更改家长数据。我可以通过编写大量代码来避免这个错误,其中一个组件
$emit
进行更改,其父组件捕获并重新发送该更改,然后一直到顶层组件,该组件最终可以更改数据,然后通过树向下渲染。虽然我得到了一个通用组件需要与其父组件无关的用例,但对于递归组件来说,它似乎效率极低

我注意到提供了官方的VueJs 2。但是查看该代码可以看出,子组件被传递了一个属于父组件的对象,但是子组件可以直接更新它(例如,在addChild或changeType方法中)

我做了一个证明。我的变体所做的只是将父对象的数据输出为json,这样您就可以看到它被更改了。一开始看起来是这样的:

{"name":"My Tree","children":[{"name":"hello"},{"name":"wat"}
然后,如果单击第一个父项,则双击
1。您好
要触发
更改类型
您会注意到父级数据现在已更改:

{"name":"My Tree","children":[{"name":"hello","children":[{"name":"new stuff"}]},{"name":"wat"}... 
…但是可怕的“避免直接变异道具”警告没有被触发。


所以我显然遗漏了一些细微差别。这是令人沮丧的,因为有这么多的问题,我害怕添加一个重复。但我觉得这是不同的,因为我在问“为什么给出的例子没有直接改变道具”

对象和数组是通过引用传递的。完全可以改变对象的属性或作为道具传递的数组的内容,因为这不会改变引用。对对象属性的更改将反映在使用特定引用的任何地方。这一点已在本文件中说明

请注意,JavaScript中的对象和数组是通过引用传递的,因此 如果道具是数组或对象,则对对象或数组本身进行变异 在子对象内部,将影响父对象状态

如果您试图将作为属性传入的对象设置为完全不同的对象,控制台中将显示警告


您是否选择利用这一点是一个设计考虑因素。在Vue树示例中,代码会改变对象属性,并且更改会反映到所有地方。一个反例可能是编辑用户。如果您有一个用户组件,并且希望对该对象的更改仅在更改被视为有效(以允许取消更改)后反映在组件外部,则您可以制作对象的内部副本,编辑副本,并在认为可以接受时发出更改。

好的,非常感谢。我想我明白了。在我的例子中,我将一个数组设置为一个新的数组,但是我可能应该通过
array.splice()
来实现这一点,所以引用仍然存在。我会试试看!