当我尝试使用组件中的方法更改数据时,为什么我的 vuex 存储状态会发生变化?
Why my vuex store state chnage when i try to chnage the data using the method in my component?
我正在制作一个小应用程序,允许用户讲述他们的网络应用程序。
但是在更新组件中我正在做的是:
- 创建组件时。
- 正在从 vue x 商店获取应用程序
- 设置数据中的值属性
- 然后根据数据 属性 将其带到模板中
但问题是当我尝试通过方法 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.
我正在制作一个小应用程序,允许用户讲述他们的网络应用程序。
但是在更新组件中我正在做的是:
- 创建组件时。
- 正在从 vue x 商店获取应用程序
- 设置数据中的值属性
- 然后根据数据 属性 将其带到模板中
但问题是当我尝试通过方法 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 increated
, but it's kind of confusing when reading the code.