在VueJS中传递一个属性对象到一个组件并在那里修改它的最佳实践是什么?
例如一个人的表格(名字,名字,年龄,性别等),点击一个条目,弹出一个对话框,在那里你可以修改条目。
如果我通过props将条目传递给组件并对其进行修改,则会收到“Error message:避免直接改变属性,因为只要父组件重新呈现,该值就会被覆盖。请改用基于属性值的数据或计算属性。”
使用计算值(这是许多教程中提出的一种可能的解决方案)也不起作用,因为在getter函数中我返回属性值,在setter函数中我将新值设置为传递的属性,然后“避免变异...”显然再次出现。
我想到的是将条目存储在Vuex.store状态中,并将其与一个计算属性一起使用。但它为每个表创建了大量代码。在我看来并不干净。
有别的解决办法吗?对我来说似乎是个基本问题。
4条答案
按热度按时间xpcnnkqh1#
只需将对象作为一个整体传递(
Object
类型的单个prop),现在就可以根据需要在子组件中修改对象的属性。是的,这被许多人认为是反模式的。他们的论点是代码很难推理是否变异遍布代码库。坦率地说,我不相信这种论点。如果我创建组件并给它命名为"PersonEditor"(例如),那么该组件做什么和为什么做就很清楚了,并且可以合理地期望它修改传入的数据...
使用Vuex(或者Pinia ......试试吧,它很棒!)也有它的价值(中央存储,时间旅行调试等),但在简单的情况下,编写(和维护)大量的样板代码只是为了坚持一些教条是不合理的......
此外,在大多数现实生活场景中,当您需要编辑一些"记录"时,您还需要其他功能。例如"取消"按钮(必须恢复用户所做的所有更改)或不传播中间值(由于用户与表单交互的过程而可能无效)复制到父级或存储区。完美的解决方案是制作对象/记录的副本(例如使用spread运算符-如果对象不包含深度嵌套的值),将其传递给组件,并在用户单击"保存"时使用事件将其取回。现在"编辑器"组件的代码简单多了,但父组件负责"提交"更改(用新对象替换原始对象)
更新
需要说明的是,有两个不同(但相似)的错误消息。一个是在运行时来自Vue本身--如果你在子程序中执行了类似
this.propA = 3
的操作。这没关系,因为这确实是一个问题......另一个可能来自ESLint,特别是它的Vue plugin/rules。规则vue/no-mutating-props。即使你做了像
this.propA.someProperty = 3
这样的事情,这一个也会咬你一口,这在技术上是正确的,但它违反了"规则"。kxeu7u2r2#
我认为,在这种情况下,最佳实践是父组件将数据作为属性传递给其子组件,然后子组件将
$emit
作为该属性的新值-这里是working DEMOApp.vue:
Child.vue:
pgvzfuti3#
修改 prop 是Vue中的一个反模式,如果你想改变 prop 值,那么就向父对象发出新的值并在那里修改它
j1dl9f464#
如果您想避免在此场景中存储,请尝试使用回调并修改父组件中的对象。此外,VueJ中必须有componentWillReceiveProps(来自React)的替代方法,也可以使用该方法来检查属性更改。