【问题标题】:How to toggle a class onclick event to only a <li> element in a list of lis using Vuejs?如何使用 Vuejs 将类 onclick 事件切换为 lis 列表中的 <li> 元素?
【发布时间】:2019-02-16 20:04:59
【问题描述】:

我正在学习一些 Vuejs 来提升我在 JS 生态系统中的表现。我正在建立一个待办事项清单。我设法呈现了一个 lis 列表。我还能够使用 onlick 事件检查它们。但是,当我单击 li 时,它会将类应用于所有这些。

我尝试遍历列表,但我认为我做得不对。如果有人可以为我指明正确的方向,请。

HTML 代码:

<div id="app">
  <h1>{{ message }}</h1>
  <ul>
    <li v-bind:class="{ completed: isActive }" v-on:click="checked" v-for="todo in todos">
      {{ todo.task }}
    </li>
  </ul>
</div>

JS代码:

var app = new Vue({
  el: '#app',
  data: {
    message: 'List of things to do today',
    todos: [
      { task: 'Have breakfast' },
      { task: 'Go to the gym' },
      { task: 'Study Vuejs' }
    ],
    isActive: false
  },
  methods: {
    checked: function(todos){
      this.isActive = !this.isActive
    }
  }
});

我需要找到一种方法来仅在我单击的 li 中切换类...

这是一个 JSfiddle 示例:https://jsfiddle.net/mercenariomode/pL3g6q14/2/

【问题讨论】:

    标签: javascript vue.js methods vuejs2


    【解决方案1】:

    如果您希望点击修改todoisActive,那么您应该将其存储(并从中读取)那里:

    <li v-for="todo in todos"
        :class="{ completed: todo.isActive }"
        @click="$set(todo, 'isActive', !todo.isActive)">
      {{ todo.task }}
    </li>
    
    data: {
      message: 'List of things to do today',
      todos: [
        { task: 'Have breakfast'},
        { task: 'Go to the gym'},
        { task: 'Study Vuejs'}
      ],
    }
    

    初始todo 的状态不需要isActive,使用$set 覆盖。

    工作小提琴:https://jsfiddle.net/iStyx/508bn4se/


    关于使用$set的说明:

    最初,todo 对象没有 isActive 属性,因此之后添加或更改它不会是反应性的。当然,您可以将isActive: false 添加到您的所有todo 对象中,但这非常混乱和草率。另一种方法是使用 Vue.$set 方法(可以通过 this.$set 从 Vue 实例中调用),它应该用于向反应对象添加新属性(它也使它们成为反应对象)。文档摘录:

    将属性添加到反应性对象,确保新属性也是反应性的,因此会触发视图更新。这必须用于向响应式对象添加新属性,因为 Vue 无法检测到正常的属性添加

    有用的阅读链接:Vue.js → Reactivity in Depth

    【讨论】:

    • 成功了!谢谢!你介意多解释一下$set() 方法吗?
    • 非常感谢。我真的很感激!
    【解决方案2】:

    你为什么不让你 todos 一个元组或对象的数组,像这样:

     todos: [
            { task: ‘Have Breakfast’, isActive: false},
            // etc...
     ]
    

    然后在您的检查方法中,过滤与名称匹配的待办事项并仅更改该属性:

    checked: function(task) {
          this.todos.filter((todo) => todo.task === task)
              .forEach((match) => match.isActive = !match.isActive)
    }
    

    然后允许您将其添加到您的模板中:

    <li v-for="todo in todos"  v-bind:class="{ completed: todo.isActive }" v-on:click="checked">
      {{ todo.task }}
    </li>
    

    在选中的函数中,您可能无法就地修改待办事项的 isActive 属性,在这种情况下,它可能会稍微复杂一些,但我相信这会为您提供要点。

    希望对您有所帮助。

    【讨论】:

    • 感谢您的回复马库斯。当我使用您的代码时,出现此控制台错误:vue:6 ReferenceError: todos is not defined at bn.checked (main.js:13) at Fe (vue:6) at HTMLLIElement.n (vue:6) at HTMLLIElement.Gr.o._wrapper (vue:6)
    • 我认为我的检查函数中有错字。请参阅上面的编辑答案。
    • 该功能开始工作,因为我在开头添加了一个 console.log 并打印了消息。
    猜你喜欢
    • 1970-01-01
    • 2018-01-31
    • 2017-04-05
    • 1970-01-01
    • 2023-02-02
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多