【问题标题】:Local component data change Vuex state when it shouldn't本地组件数据在不应该更改 Vuex 状态时更改
【发布时间】:2020-03-16 11:42:28
【问题描述】:

我有一个名为EditUser.vue的组件,它使用vue路由器链接到路由器系统,这是该组件的路由定义

{
 path: "/users/:id/edit",
 name: "Edit User",
 props: true,
 component: () => import(/* webpackChunkName "edit-user" */ "@/views/EditUser.vue"),
 beforeEnter: (to, from, next) => {
   if (!store.getters.isLogged) next("/");
   else next();
 }
},

启用 props 非常简单,因为它需要获取用户 ID。

组件本身就是这个

<template>
<main class="h-creen p-3">

      <Input
        type="text"
        name="name"
        label="name"
        v-model="user.name"
        required
      />
</main>
</template>

<script>
import { mapState } from "vuex";
import Input from "@/components/Input.vue";

export default {
  name: "EditUserView",

  props: {
    id: {
      required: true,
      type: String,
    }
  },

  components: {
   Input,
  },

  data: () => ({
    user: {},
   }),

  async beforeMount() {
    // TODO move into router file
    if (this.users.length <= 0) {
      this.$router.push("/users");
    }

    this.user = this.users.find(user => user.id == this.id);
  },

  computed: mapState(["users"])
  };
</script>

我已经省略了无用的部分,这段代码无论如何都会复制问题。 &lt;Input&gt; 只是标签的包装器和带有一些样式的输入,没有什么神奇之处。

问题是,如果我在输入中键入一些内容,我希望 this.users 会被修改,它会发生这种情况,但它不应该修改 Vuex 状态内的相同记录,但会发生这种情况,我不明白为什么.换句话说,如果我使用输入编辑名称,此修改会在状态上传播,从而在其他视图中呈现,但它不应该因为它是本地数据。

我在这里错过了什么?

【问题讨论】:

  • 不是 100% 确定,但您将用户映射到 this.users。由于对象在 javascript 中通过引用传递,因此您的更改可能会传播回您的 vuex
  • 不应该,因为它是本地数据 - 它不是本地数据,因为您使用的是全局状态。正如已经提到的,用户对象是通过引用传递的。请解释该组件应该如何工作。是否应该通过提交按钮将更改提交回全局状态?
  • @EstusFlask 是的,我的意图是

标签: javascript vue.js vuex vue-router


【解决方案1】:

这导致分配对现有对象的引用:

this.user = this.users.find(user => user.id == this.id);

user.name属性被v-model双向绑定改变时,相应的嵌套对象在users中被修改。

数据应该被浅拷贝到本地(根据情况可能需要深拷贝):

this.user = {...this.users.find(user => user.id == this.id)};

然后this.user 应在需要时复制回this.users

或者组件不应该有自己的user,它可以包含单独的字段:

  <Input
    type="text"
    name="name"
    label="name"
    v-model="name"
    required
  />

name等需要的时候可以复制回this.users

【讨论】:

  • 有趣。我发誓我在某处读到find() 是按值分配的,但显然我错了。我将尝试此修复并返回此处接受此答案。
  • 没有内置函数对对象进行深度复制,这很昂贵并且弊大于利,如果按值复制,您将不会高兴,因为这样它们每个对象都是不同的对象时间,this.users.find(...) !== this.users.find(...)。它是在 JS 中设计的引用 - 除非它是原始的。
  • 请原谅我的无知我仍然是 Javascript 的新手,感谢您提供的有用建议。我今天学到了一些有价值的东西
猜你喜欢
  • 1970-01-01
  • 2020-02-28
  • 2019-06-08
  • 2021-01-23
  • 2021-10-08
  • 2016-06-25
  • 1970-01-01
  • 2019-03-20
  • 2011-01-25
相关资源
最近更新 更多