javascript - Vue - 发出一个数据对象但改变一个会改变它们
问题描述
我有一个 TODO 应用程序,想通过道具从一个组件传递到另一个对象数组。每次单击按钮时都会添加一个对象,但我遇到了麻烦。问题是添加到数组中的每个对象的属性值都相同。似乎它没有正确保存每个tareas.tarea
数据。
应用程序.vue
<template>
<div>
<Header></Header>
<AgregarTarea @tareaAgregada="agregarTarea"></AgregarTarea>
<div class="container">
<div class="columns">
<div class="column">
<Lista :tareas = 'tareas' @eliminarItem="eliminarTarea"></Lista>
<!-- here i pass through props the array of objects -->
</div>
<div class="column">
<TareaFinalizada></TareaFinalizada>
{}
</div>
</div>
</div>
</div>
</template>
<script>
import Header from './components/Header'
import AgregarTarea from './components/AgregarTarea'
import Lista from './components/Lista'
import TareaFinalizada from './components/TareaFinalizada'
export default {
data(){
return {
tareas:[]
}
},
components: {
Header,
AgregarTarea,
Lista,
TareaFinalizada
},
methods: {
agregarTarea(data){
//add new object to the array
this.tareas.push(data)
},
eliminarTarea(data) {
this.tareas.splice(data.id, 1);
}
}
};
</script>
AgregarTarea.vue || 这是我添加新 ToDo 的地方
<template>
<div class="container">
<input class="input" type="text" placeholder="Text input" v-model="tareas.tarea">
<button class="button is-primary" @click="agregarTarea">Agregar Tarea</button>
</div>
</template>
<script>
export default {
data(){
return {
tareas: {
tarea:'',
id:null,
editar:false
}
}
},
methods: {
agregarTarea(){
this.$emit('tareaAgregada', this.tareas)
this.tareas.tarea = ' ';
}
}
}
</script>
Lista.vue || 这里是我展示 ToDo 的地方
<template>
<div>
<div class="list is-hoverable">
<ul>
<li v-for="(tarea, index) in tareas" :key="index">
<a class="list-item has-text-centered" @click="editarTexto(index)">
{{ tarea }}
<div class="editar" v-if="editar">
<input class="input" type="text" placeholder="Text input" v-model="nuevaTarea">
</div>
</a>
<button class="button is-danger" @click="eliminarItem(index)">Eliminar</button>
<div><input type="checkbox"> Finalizada</div>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props:['tareas'],
data(){
return {
nuevaTarea: ' ',
editar:false,
}
},
methods: {
eliminarItem(index){
this.$emit('eliminarItem', index)
},
editarTexto(){
this.editar = true
}
}
}
</script>
<style scoped>
</style>
解决方案
JavaScript 对象是按引用传递的(不是按值克隆的)。每次从AgregarTarea.vue 获取$emit
对象时,它都是与以前相同的对象引用,即使属性已更改。因此, App.vue中数组中的所有对象都是同一个对象。tareas
tareas
要解决此问题,请每次将AgregarTarea.vue更改$emit
为克隆:
methods: {
agregarTarea(){
this.$emit('tareaAgregada', Object.assign({}, this.tareas)) // clone
this.tareas.tarea = ' ';
}
}
(这是一个浅克隆,如果有嵌套对象将无法正常工作this.tareas
,但事实并非如此。)
选项#2
这是一种适用于嵌套对象的不同方式:
new Vue({
el: "#app",
data(){
return {
tareas: null // <-- It's not filled here
}
},
methods: {
resetTareas() { // <-- it's filled here instead
this.tareas = {
tarea:'',
id:null,
editar:false
}
},
agregarTarea(){
this.$emit('tareaAgregada', this.tareas);
this.resetTareas(); // <-- Create a brand new object after emitting
}
},
created() {
this.resetTareas(); // <-- This is for the first one
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
Tarea: <input type="text" v-model="tareas.tarea" /><br /><br />
<button @click="agregarTarea">Emit</button><br /><br />
Object: {{ tareas }}
</div>
由于resetTareas
每次都会创建一个全新的对象,因此您不必担心克隆任何内容,即使tareas
是复杂的嵌套对象也可以使用。
推荐阅读
- java - 通过 ContentDescription 从 textview 获取文本
- c# - GroupBy KeySelector 函数是什么样的?
- java - 通过 java 代码清除 akamai 中的缓存 URL?
- node.js - 在 Javascript (Node.js) 中,是否可以将已经实例化的类对象传递给另一个代码模块
- sql-server - 升级 Visual Studio 后 SSIS 包无法运行
- javascript - 如何计算 TDOA(到达时间差)的清晰简单示例
- javascript - jquery $().contents() 给我 [object Object]
- javascript - 更改按钮css javascript的背景透明度
- python - 如何从 pytorch 网络中删除 maxpooling 层
- c - 数组的整数子集的总和,获取所有结果而不是第一个结果