当我尝试使用组件中的方法更改数据时,为什么我的 vuex 存储状态会发生变化?

Why my vuex store state chnage when i try to chnage the data using the method in my component?

我正在制作一个小应用程序,允许用户讲述他们的网络应用程序。

但是在更新组件中我正在做的是:

但问题是当我尝试通过方法 addTechToStack 将新值推送到 app_stacks 列表的末尾来更新应用程序堆栈时,它还会更改 vuex 状态的数据

代码如下

<template>
  <div>
    <div class="section">
      <div class="box">
        <h1 class="title is-4 has-text-centered">Update App</h1>
        <hr class="has-background-black" />
        <form method="POST" @submit.prevent="">
          <div class="field">
            <label class="label">App Name:</label>
            <div class="control">
              <input
                class="input"
                type="text"
                placeholder="Enter App Name"
                v-model="updated.app_name"
              />
            </div>
          </div>
          <div class="field">
            <label class="label">App Subtitle:</label>
            <div class="control">
              <input
                class="input"
                type="text"
                placeholder="Enter App Subtitle"
                v-model="updated.app_subtitle"
              />
            </div>
          </div>
          <div class="field">
            <label class="label">App Url:</label>
            <div class="control">
              <input
                class="input"
                type="text"
                placeholder="Enter App Url"
                v-model="updated.app_url"
              />
            </div>
          </div>
          <div class="field">
            <label class="label">App Category:</label>
            <div class="control">
              <div class="select">
                <select v-model="updated.app_category">
                  <option value="" disabled>Select Category</option>
                  <option
                    v-for="(category, index) in categoreis"
                    :key="index"
                    :value="category"
                    >{{ category }}</option
                  >
                </select>
              </div>
            </div>
          </div>
          <div class="field">
            <label class="label">App Description:</label>
            <textarea
              class="textarea"
              placeholder="Description of your app"
              v-model="updated.app_description"
            ></textarea>
          </div>
          <!-- IMP:Stack section  -->
          <div class="field">
            <label class="label">App Stacks:</label>
            <div class="field has-addons">
              <div class="control">
                <input
                  class="input"
                  type="text"
                  placeholder="Find Technology"
                  v-model="updated.stackTech"
                  id="stackTech"
                />
              </div>
              <div class="control">
                <button class="button is-info" @click="addTechToStack">
                  Add
                </button>
              </div>
            </div>
          </div>
          <div class="box">
            <label class="label">Stacks:</label>

            <span
              class="tag is-medium mr-3"
              v-for="(tech, index) in updated.app_stacks"
              :key="index"
              >{{ tech }}
              <button
                class="delete is-small"
                @click="removeStack(index)"
              ></button>
            </span>
          </div>
          <!-- Stack section ends -->
          <div class="field is-grouped">
            <p class="control">
              <a class="button">
                Cancel
              </a>
            </p>
            <p class="control">
              <button
                type="submit"
                class="button is-primary"
                v-on:click="submitUpdate"
              >
                Update
              </button>
            </p>
          </div>
        </form>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Update",
  data() {
    return {
      currentApp: null,
      categoreis: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"],
      //   Contains the updated value
      updated: {
        app_name: "",
        app_subtitle: "",
        app_description: "",
        app_url: "",
        app_category: "",
        app_stacks: "",
        stackTech: "",
      },
    };
  },

  methods: {
    removeStack(index) {
      console.log("Removed");
      this.updated.app_stacks.splice(index, 1);
      console.log(this.currentApp);
      console.log(this.updated.app_stacks);
    },
    addTechToStack() {
      this.updated.app_stacks.push(this.updated.stackTech);
      console.log(this.currentApp.stacks);
      console.log(this.updated.app_stacks);
    },
    submitUpdate() {
      // Check if user has updated any content
      if (
        this.currentApp.app_name == this.updated.app_name &&
        this.currentApp.subtitle == this.updated.app_subtitle &&
        this.currentApp.app_url == this.updated.app_url &&
        this.currentApp.category == this.updated.app_category &&
        this.currentApp.description == this.updated.app_description &&
        this.currentApp.stacks.toLocaleString()==this.updated.app_stacks.toLocaleString()
      ) {
        console.log("Cannot Update Beasue every vlaue is the same");
        console.log(this.currentApp.description);
        console.log(this.updated.app_description);
        console.log(this.currentApp.stacks);
        console.log(this.updated.app_stacks);
      } else {
        console.log("Updated");
        console.log(this.currentApp.description);
        console.log(this.updated.app_description);
      }
    },
  },
  created() {
    // const current = this.$store.state.your_apps[this.$route.params.index];
    this.currentApp = this.$store.state.your_apps[this.$route.params.index];
    this.updated.app_name = this.currentApp.app_name;
    this.updated.app_subtitle = this.currentApp.subtitle;
    this.updated.app_url = this.currentApp.app_url;
    this.updated.app_category = this.currentApp.category;
    this.updated.app_description = this.currentApp.description;
    this.updated.app_stacks = this.currentApp.stacks;
    console.log(this.currentApp);
  }
};
</script>

问题是您将同一对象(数组)的引用分配给不同的变量。

所以this.updated.app_stacks === this.currentApp.stacks都是对同一个数组的引用。所以如果你改变一个,你就会改变另一个。

为避免这种情况,您必须创建此数组的副本,以便创建新引用并分离两个数组。

如果数组托管原始值(即不是数组或对象),则可以进行浅表复制。有很多方法可以做到这一点,这里是一个:

  this.updated.app_stacks = [...this.currentApp.stacks];

Side note: in your data() initialisation, this.updated.app_stacks should be an empty array, not an empty string. It doesn't change anything since you overwrite it in created, but it's kind of confusing when reading the code.