[英]Updating an input's bound value when edited
我正在开发一个基本的待办事项应用程序。 每个待办事项/任务项都被列为 Vue <list-item>
组件中的输入项,并且<list-item>
显示为带有指向任务数组的 v-for。
我试图让用户编辑每个任务输入,并在更改值后,更新数组项(而不仅仅是输入本身)。 我在输入上的@change 事件正在触发,但我不知道在此之后该怎么做。
https://jsfiddle.net/xbxm7hph/
HTML:
<div class="app">
<div class="add-control-area columns is-mobile is-multiline">
<responsive-container>
<div class="field is-grouped">
<div class="control is-expanded">
<input class="input add-control-text" type="text" placeholder="New Task" v-model="newTask" v-on:keyup.enter="addTask">
</div>
<div class="control">
<a class="button is-white add-control-button" @click="addTask" :disabled="!isThereText">Add Task</a>
</div>
</div>
</responsive-container>
<responsive-container>
<list-item v-for="task, index in tasks" :item="task" :index="index" @task-completed="completeTask(index)" @task-deleted="deleteTask(index)" ></list-item>
</responsive-container>
</div>
</div>
JS:
Vue.component('list-item', {
props: ['item', 'index'],
template: `<div class="task-wrapper">
<input class="task" :value="item" @change="updateTask()">
<div class="task-control delete-task" @click="deleteTask()"></div>
<div class="task-control complete-task" @click="completeTask()"></div>
</div>
`,
methods: {
completeTask: function() {
this.$emit('task-completed', this.index);
},
deleteTask: function() {
this.$emit('task-deleted', this.index);
},
updateTask: function() {
console.log('changed');
}
}
});
Vue.component('responsive-container', {
template: `
<div class="column is-4-desktop is-offset-4-desktop is-10-tablet is-offset-1-tablet is-10-mobile is-offset-1-mobile">
<div class="columns is-mobile">
<div class="column is-12">
<slot></slot>
</div>
</div>
</div>
`
});
var app = new Vue({
el: '.app',
data: {
tasks: [],
completedTasks: [],
newTask: ''
},
methods: {
addTask: function() {
if(this.isThereText) {
this.tasks.push(this.newTask);
this.newTask = '';
this.updateStorage();
}
},
completeTask: function(index) {
this.completedTasks.push(this.tasks[index]);
this.tasks.splice(index, 1);
this.updateStorage();
},
deleteTask: function(index) {
this.tasks.splice(index, 1);
this.updateStorage();
},
updateStorage: function() {
localStorage.setItem("tasks", JSON.stringify(this.tasks));
}
},
computed: {
isThereText: function() {
return this.newTask.trim().length;
}
},
// If there's already tasks stored in localStorage,
// populate the tasks array
mounted: function() {
if (localStorage.getItem("tasks")) {
this.tasks = JSON.parse(localStorage.getItem("tasks"));
}
}
});
在<list-item>
组件上使用v-model
指令,而不是传入item
属性。 您还需要从数组 ( tasks[index]
) 中传递一个引用,因为此范围内的task
是未绑定到数组元素的副本:
<list-item v-for="task, index in tasks" v-model="tasks[index]"></list-item>
在列表项的组件定义中,您现在需要接受一个value
属性(这是使用v-model
时传递的内容)并将数据属性item
设置为该值。 然后,在更改时发出input
事件以传递item
值(这是组件在使用v-model
时正在侦听的内容):
Vue.component('list-item', {
props: ['value'],
template: `<div class="task-wrapper">
<input class="task" v-model="item" @change="updateTask"></div>
</div>
`,
data() {
return {
item: this.value,
}
},
methods: {
updateTask: function() {
this.$emit('input', this.item);
}
}
});
正如 Bert Evans 所提到的,即使这有效,Vue 要求使用v-for
指令的组件也使用key
属性(否则你会收到来自 Vue 的警告):
<list-item v-for="task, index in tasks" :key="index" v-model="tasks[index]" ></list-item>
此外,要意识到v-for
范围内的index
变量可以更改,这意味着索引 1 处的项目可能会更改为索引 4,这可能会随着应用程序变得更加复杂而带来一些问题。 更好的方法是将items
存储为具有id
属性的对象。 这样,您就可以拥有与该项目关联的不可变 id。
您可以将索引和新值传递给您的更改事件处理程序:
<input class="task" :value="item" @change="updateTask(index, $event)">
然后相应地访问它们:
updateTask: function(index, event) {
console.log(index);
console.log(event.target.value);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.