用v-for反转点击时的布尔值?

时间:2018-09-19 13:24:18

标签: vue.js vuejs2

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。我不确定自己在做什么错。我什至不确定这是否是最好的方法。我的主要问题是我不确定为什么会这样。

非常感谢您的帮助!

3 个答案:

答案 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中的“任务”列表:

enter image description here

在这种情况下,这是您必须执行的事件时间表:

  • 加载客户端页面,初始化Vue后,vue组件将调用您的Web服务以获取任务列表,然后将其打印出来。
  • 然后,当我单击任务时,您必须(通过另一条路线)对Web服务进行另一个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;

        }
    }