JS和VueCLI的入门者,所以我会尽力解释。我正在使用Express作为后端。
我试图在单击时更改对象数组中的布尔值。我能够做到这一点,但是当我在v-for循环中单击另一个列表项时,它将在数组的所有其他索引中翻转布尔值。这是我的代码:
快递:/路线:
// fake data store
const tasks = [
{ id: 1, task: 't1', completed: false},
{ id: 2, task: 't2', completed: false},
{ id: 3, task: 't3', completed: false}
];
/**
* GET handler for /tasks route
* @returns {Array.<{id: Number, task: String, completed: Boolean}>} array of task objects
*/
router.get('/', (req, res) => {
res.send(tasks);
});
Webapp:
/**
* GET /tasks
* @returns Promise => {Array.<{id: Number, task: String, completed: Boolean}>} array of task objects
*/
export function getTasks() {
return request('tasks');
}
现在是我的Vue组件:
<template>
<div id="tasks">
<h2>Movies to Add</h2>
<ul class="todo-list">
<li v-for='task in tasks' :id="task.id" v-on:click="completeMovie($event)" :key='task.id' class="todo-list__li">
<input class="todo-list__input" type="checkbox" :name='task.task' :id="task.task">
<div class="todo-list__checkbox">
<span class="todo-list__checkbox-inner"><i></i></span>
</div>
<label :for='task.task'>{{ task.task }}</label>
</li>
</ul>
</div>
</template>
<script>
import {getTasks} from './../../services/tasks';
export default {
name: 'TaskList',
data: function() {
return {
tasks: []
};
},
created: function() {
getTasks()
.then(res => this.tasks = res);
},
methods: {
completeMovie: function (event) {
var taskId = event.currentTarget.id -1;
getTasks()
.then((res) => {
this.tasks = res;
res[taskId].completed = !res[taskId].completed;
});
}
}
}
</script>
因此,当我单击第一个列表项时,它将任务:t1更改为True,但是如果我单击第二个列表项,则将t1更改为False,将t2更改为True。我不确定自己在做什么错。我什至不确定这是否是最好的方法。我的主要问题是我不确定为什么会这样。
非常感谢您的帮助!
答案 0 :(得分:2)
您可能过于复杂了。
您需要的只是
<li v-for="task in tasks" :key="task.id"
@click="task.completed = !task.completed"
class="todo-list__li">
演示〜https://jsfiddle.net/xy1q0auL/2/
每次单击都无须(显然)重新获取任务。这就是为什么您以前的更改会被重置的原因;这是因为您用getTasks()
中未修改的值覆盖了所有数据。
答案 1 :(得分:0)
当调用completeMovie()时,您将HTTP请求发送到服务器,该请求将发回给您未更改的任务列表。我不清楚您要达到的目标,但是您在诺言中的回叫没有任何意义。在回调中,您将重新影响Vue中的“任务”列表:
在这种情况下,这是您必须执行的事件时间表:
答案 2 :(得分:0)
您可以简单地做到这一点:
<li v-for='task in tasks' :id="task.id" v-on:click="completeMovie(task.id)" :key='task.id' class="todo-list__li">
<input class="todo-list__input" type="checkbox" :name='task.task' :id="task.task">
<div class="todo-list__checkbox">
<span class="todo-list__checkbox-inner"><i></i></span>
</div>
<label :for='task.task'>{{ task.task }}</label>
</li>
该方法的答案
completeMovie: function ($taskId) {
this.tasks[$taskId].completed = !this.tasks[$taskId].completed;
}
}