vue.js - 如何制作一个包含附加到 v-for 指令切换状态中的对象的复选框的列表(不切换列表中的其他复选框)?

标签 vue.js vuejs2

我正在尝试制作一个使用 VueJS (2.x) 的客户端待办事项列表。这是我的 HTML:

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>To-do List</title>
        <link href="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a6c4c9c9d2d5d2d4c7d6e69388948894" rel="noreferrer noopener nofollow">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
    </head>
    <body>
        
        <div id="app">
            <h1>To-do List</h1>
            <h2>Completed Tasks!</h2>
            <ul>
                <li v-for="item in complete">{{ item.description }}<input type="checkbox" :checked="item.done" @change="item.done = false"></li>
            </ul>
            <h2>Uncompleted Tasks!</h2>
            <ul>
                <li v-for="item in uncomplete">{{ item.description }}<input type="checkbox" :checked="item.done" @change="item.done = true"></li>
            </ul>
        </div>
        
        <script src="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="295f5c4c691b071e07181a" rel="noreferrer noopener nofollow">[email protected]</a>/dist/vue.js"></script>
        <script type="module" src="scripts/app.js"></script>
    </body>
    </html>

然后在scripts/app.js 中我这样做了:

    'use strict'
    
    let app = new Vue({
    
        el      : "#app",
        data    : {
            tasks: [
                { description: 'Say Hello', done: true },
                { description: 'Review Code', done: false },
                { description: 'Read Emails', done: false },
                { description: 'Reply to Emails', done: false },
                { description: 'Wash The Dishes', done: true },
                { description: 'Stop Working', done: true },
            ]
        },
        computed : {
            complete : function() {
                return this.tasks.filter(task => task.done === true);
            },
            uncomplete : function() {
                return this.tasks.filter(task => task.done === false);
            }
        }
    
    });

我的问题很简单:当我更改给定列表中复选框的状态(选中或取消选中它)时,紧随其后的复选框也会切换状态。

我不明白为什么会发生这种情况以及如何解决它。如果有人能告诉我为什么会发生这种情况(这样我就不必在我行为不端v-for/switch-state时回到这里)以及如何修复它,那就太棒了!

最佳答案

  1. 首先。 data中最好使用Function,而不是Object,否则可能会导致更新错误。

因为 Function 仅在组件定义中使用时才被接受。

// wrong
data: {
    tasks: []
}

// correct
data() {
    return {
        task: []
    }
}
  • 您不能直接更改 compulated 属性,该属性默认只有一个 Compulated Getter。如果您想处理 compated 属性,请给出 Computed Setter到它。
  • // wrong
    computed: {
        complete(){
          return this.tasks.filter(task => task.done === true);
        },
    }
    
    // right
    computed: {
        complete: {
            get() {
                return this.tasks.filter(task => task.done === true);
            },
            set(value) {
                this.task.forEach((task, index) => {
                    let matched = value.find(({ description }) => description === task.description);
                    if(matched) {
                        this.task[index] = matched;
                    }
                });
            }
        }
    }
    
  • 无法通过 v-for 绑定(bind)值,因为 vue2 无法识别数组中的更改。
  • <!-- wrong -->
    <li
      v-for="item in complete">
      {{ item.description }}
      <input
        type="checkbox"
        :checked="item.done"
        @change="item.done = false">
    </li>
    
    <!-- correct -->
    <li
      v-for="(item, index) in complete">
      {{ item.description }}
      <input
        type="checkbox"
        :checked="item.done"
        @change="complete[index].done = false">
    </li>
    

    new Vue({
      el: "#app",
      data() {
        return {
          tasks: [
            { description: 'Say Hello', done: true },
            { description: 'Review Code', done: false },
            { description: 'Read Emails', done: false },
            { description: 'Reply to Emails', done: false },
            { description: 'Wash The Dishes', done: true },
            { description: 'Stop Working', done: true },
          ]
        };
      },
      computed : {
        complete: {
          get() {
            return this.tasks.filter(task => task.done === true);
          },
          set(value) {
            this.task.forEach((task, index) => {
              let matched = value.find(({ description }) => description === task.description);
              if(matched) {
                  this.task[index] = matched;
              }
            });
          }
        },
        uncomplete: {
          get() {
            return this.tasks.filter(task => task.done === false);
          },
          set(value) {
            this.task.forEach((task, index) => {
              let matched = value.find(({ description }) => description === task.description);
              if(matched) {
                  this.task[index] = matched;
              }
            });
          }
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <h1>To-do List</h1>
      <h2>Completed Tasks!</h2>
      <ul>
        <li
          v-for="(item, index) in complete">
          {{ item.description }}
          <input
            type="checkbox"
            v-model="complete[index].done">
        </li>
      </ul>
      <h2>Uncompleted Tasks!</h2>
      <ul>
        <li
          v-for="(item, index) in uncomplete">
          {{ item.description }}
          <input
            type="checkbox"
            v-model="uncomplete[index].done">
        </li>
      </ul>
    </div>

    关于vue.js - 如何制作一个包含附加到 v-for 指令切换状态中的对象的复选框的列表(不切换列表中的其他复选框)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74206815/

    相关文章:

    javascript - 无法通过插件访问Vue.js全局函数

    vue.js - Nuxt基于域名的动态布局?

    javascript - 如何在 Vue.js 中使用从一个钩子(Hook)到另一个钩子(Hook)的数据?

    javascript - 如何在尚未评估变量的情况下将变量传递给自定义组件?

    javascript - 使用 css 和 vue 在单击或选定的元素上显示事件边框

    javascript - 如何使用 Vue.js 为数组(数据)中的所有对象添加属性?

    javascript - Vue.js 使用 post 方法重定向

    javascript - v-for for 作为 props 传递的数组会引发错误

    vue.js - Nuxtjs : Vue packages version mismatch: vue@3. 2.22 和 vue-server-renderer@2.6.14

    Vue.js 以特定方式自动注册 Vuex 模块