将VueJS中的属性对象传递给组件并在那里修改它的最佳实践是什么?
例如,一个人的表(姓名,名字,年龄,性别等),点击一个条目,弹出一个对话框,您可以修改条目。
如果我通过props将条目传递给组件并修改它,我会得到"错误消息:避免直接改变prop,因为每当父组件重新呈现时,该值将被覆盖。相反,使用基于prop值的data或computed属性。">
使用计算值(这是一个可能的解决方案,从很多教程等提出)不工作,因为在getter函数我返回属性值,并在setter函数我设置新值传递的属性,然后"避免变异…";显然又出现了
我想到的是将条目存储在Vuex中。存储状态并将其与计算属性一起使用。但是它会为每个表创建大量代码。我看不干净。
是否有其他解决方案?对我来说似乎是一个基本问题。
只需将对象作为一个整体传递(单个类型为Object
的prop),现在您可以根据需要修改子组件中对象的属性。
是的,这被许多人认为是反模式的。他们的论点是,如果代码库中到处都是突变,代码就很难推理。坦率地说,我不同意这种说法。如果我创建组件并给它命名为personeditor;(例如)非常清楚该组件的作用和原因,并且有理由期望它修改传入…
的数据。使用Vuex(或Pinia…)也有它的价值(中央存储,时间旅行调试等),但在简单的情况下,我认为编写(和维护)大量的样板代码只是为了坚持一些教条是不合理的…
在大多数现实生活场景中,当您需要编辑一些"记录"时,您还需要其他功能。例如"Cancel"按钮(用户所做的所有更改都必须恢复),或者不将中间值(由于用户与表单交互的过程可能无效)传播到父值或存储。完美的解决方案是复制对象/记录(例如使用扩展操作符-如果对象不包含深度嵌套的值),将其传递给组件,并在用户单击"保存"时使用事件将其获取回来。现在是"编辑器"的代码组件要简单得多,但是父组件负责"提交"。更改(将原对象替换为新对象)
更新澄清一下。有两个不同(但相似)的错误消息。一个是在运行时来自Vue本身——如果你在子进程中做this.propA = 3
之类的事情。这很好,因为这确实是个问题……
另一个可以来自ESLint,特别是它的Vue插件/规则。规则value/no-mutating-props。即使你做了像this.propA.someProperty = 3
这样的操作,它也会咬你,这在技术上是正确的,但它违反了
我认为,在这种情况下,最好的做法是父组件将数据作为道具传递给它的子组件。然后,子组件$emit
作为该道具的新值—这是一个工作的DEMO
App.vue:
<template>
<div>
<h1>{{ title }}</h1>
<Child @changeTitle="ChangeT($event)" />
</div>
</template>
<script>
import Child from "./components/Child";
export default {
name: "App",
components: {
Child,
},
data() {
return {
title: "Rick Grimes",
};
},
methods: {
ChangeT(title) {
this.title = title;
},
},
};
</script>
<style></style>
Child.vue:
<template lang="html">
<button type="button" @click='passEvent'> Update me</button>
</template>
<script>
export default {
name: "Child",
methods: {
passEvent() {
this.$emit("changeTitle", "Awesome ");
},
},
};
</script>
<style lang="css" scoped>
</style>
在Vue中,改变props是一个单元模式,如果你想改变props的值,那么向parent发送新值并在那里修改它
如果您想避免在此场景中存储,请尝试使用回调并修改父组件中的对象。此外,在VueJs中必须有一个componentWillReceiveProps(来自React)的替代方案,也可以使用它来持续检查props的更改。