Данные локального компонента изменяют состояние Vuex, когда это не должно - PullRequest
2 голосов
/ 16 марта 2020

У меня есть компонент с именем 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();
 }
},

Довольно просто с включенными подпорками, потому что ему нужно получить идентификатор пользователя.

Сам компонент такой:

<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>

Я опустил ненужные части, этот код все равно повторяет проблему. <Input> - это просто обертка для метки и ввода с некоторым стилем, там нет ничего волшебного c.

Проблема в том, что если я введу что-то во ввод, я ожидаю, что this.users будет изменен, что это происходит, но это не должно изменить ту же запись в состоянии Vuex, но это происходит, и я не понимаю, почему. Другими словами, если я редактирую имя, используя входные данные, эта модификация распространяется на состояние, таким образом, отображается в других представлениях, но не должна, поскольку это локальные данные.

Что мне здесь не хватает?

1 Ответ

1 голос
/ 16 марта 2020

Это приводит к присвоению со ссылкой на существующий объект:

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 и т. Д. c. при необходимости можно скопировать обратно в this.users.

...