如何将VueJS中的属性对象传递给组件进行修改?

8dtrkrch  于 2023-02-09  发布在  Vue.js
关注(0)|答案(4)|浏览(268)

在VueJS中传递一个属性对象到一个组件并在那里修改它的最佳实践是什么?
例如一个人的表格(名字,名字,年龄,性别等),点击一个条目,弹出一个对话框,在那里你可以修改条目。
如果我通过props将条目传递给组件并对其进行修改,则会收到“Error message:避免直接改变属性,因为只要父组件重新呈现,该值就会被覆盖。请改用基于属性值的数据或计算属性。”
使用计算值(这是许多教程中提出的一种可能的解决方案)也不起作用,因为在getter函数中我返回属性值,在setter函数中我将新值设置为传递的属性,然后“避免变异...”显然再次出现。
我想到的是将条目存储在Vuex.store状态中,并将其与一个计算属性一起使用。但它为每个表创建了大量代码。在我看来并不干净。
有别的解决办法吗?对我来说似乎是个基本问题。

xpcnnkqh

xpcnnkqh1#

只需将对象作为一个整体传递(Object类型的单个prop),现在就可以根据需要在子组件中修改对象的属性。
是的,这被许多人认为是反模式的。他们的论点是代码很难推理是否变异遍布代码库。坦率地说,我不相信这种论点。如果我创建组件并给它命名为"PersonEditor"(例如),那么该组件做什么和为什么做就很清楚了,并且可以合理地期望它修改传入的数据...
使用Vuex(或者Pinia ......试试吧,它很棒!)也有它的价值(中央存储,时间旅行调试等),但在简单的情况下,编写(和维护)大量的样板代码只是为了坚持一些教条是不合理的......
此外,在大多数现实生活场景中,当您需要编辑一些"记录"时,您还需要其他功能。例如"取消"按钮(必须恢复用户所做的所有更改)或不传播中间值(由于用户与表单交互的过程而可能无效)复制到父级或存储区。完美的解决方案是制作对象/记录的副本(例如使用spread运算符-如果对象不包含深度嵌套的值),将其传递给组件,并在用户单击"保存"时使用事件将其取回。现在"编辑器"组件的代码简单多了,但父组件负责"提交"更改(用新对象替换原始对象)

更新

需要说明的是,有两个不同(但相似)的错误消息。一个是在运行时来自Vue本身--如果你在子程序中执行了类似this.propA = 3的操作。这没关系,因为这确实是一个问题......
另一个可能来自ESLint,特别是它的Vue plugin/rules。规则vue/no-mutating-props。即使你做了像this.propA.someProperty = 3这样的事情,这一个也会咬你一口,这在技术上是正确的,但它违反了"规则"。

kxeu7u2r

kxeu7u2r2#

我认为,在这种情况下,最佳实践是父组件将数据作为属性传递给其子组件,然后子组件将$emit作为该属性的新值-这里是working 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>
pgvzfuti

pgvzfuti3#

修改 prop 是Vue中的一个反模式,如果你想改变 prop 值,那么就向父对象发出新的值并在那里修改它

j1dl9f46

j1dl9f464#

如果您想避免在此场景中存储,请尝试使用回调并修改父组件中的对象。此外,VueJ中必须有componentWillReceiveProps(来自React)的替代方法,也可以使用该方法来检查属性更改。

相关问题