简体   繁体   English

Vue.js - 单击事件和“this”

[英]Vue.js - click events and "this"

I have a todo list in vue and I'm using pop() to clear out/delete list items.我在 vue 中有一个待办事项列表,我正在使用pop()清除/删除列表项。 See the code in question below:请参阅下面有问题的代码:

 // components Vue.component('todoitem', { template: "<li>Test Item</li>" }) // app code var app = new Vue({ el: '#app', data: { todos: [ { text: 'Sample Item 1' }, { text: 'Sample Item 2' }, { text: 'Sample Item 3' } ], button: { text: 'Hide' }, seen: true }, methods: { addItem: function() { let item = document.getElementById("list-input").value; let error = document.getElementById("error"); if (item == "") { error.style.display = "block"; } else { app.todos.push({ text: item }); error.style.display = "none"; } }, removeItem: function() { this.todos.pop(); }, toggleSeen: function() { app.seen = !app.seen; app.button.text = app.seen ? 'Hide' : 'Show'; } } });
 .todo-list { list-style-type: square; } .todo-list__delete { display: none; } li:hover .todo-list__delete { display: inline-block; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script> <div id="app"> <ul class="todo-list"> <li v-for="todo in todos"> {{ todo.text }} <a v-on:click="removeItem" class="todo-list__delete" href="#">Delete</a> </li> </ul> <input type="text" id="list-input"> <input type="submit" id="list-submit" v-on:click="addItem"> <span id="error" style="color: red; display: none;">Please Enter Text</span> <ul> <todoitem></todoitem> </ul> <h2 v-if="seen">SEEN</h2> <button id="hide-seen" v-on:click="toggleSeen">{{ button.text }}</button> </div>

The expected behavior is that when delete is clicked, it invokes the removeItem function and with the usage of this in that function it deletes the selected item.预期的行为是,当单击删除时,它会调用 removeItem 函数,并在该函数中使用this删除所选项目。 However what actually happens is it just deletes nodes starting from the bottom.然而,实际发生的是它只是从底部开始删除节点。

I thought the issue is that with this I'm actually referencing the delete link and not actually the <li> element I'm trying to remove.认为这个问题是与this实际上我引用删除链接,而不是实际的<li>元素我试图删除。 So I tried both:所以我尝试了两者:

removeItem: function() {
    this.todos.parentElement.pop();
}

And:和:

removeItem: function() {
    this.parentElement.todos.pop();
}

With no luck.没有运气。

How does this work in Vue? this在 Vue 中是如何工作的?

In that context, this refers to the Vue component (not the DOM element).在这种情况下, this指的是 Vue 组件(而不是 DOM 元素)。 this.todos is the todos array inside the component's data object, and pop removes the last item of an array. this.todos是组件data对象内的todos数组, pop删除数组的最后一项。 So that's why the last element is being removed.这就是为什么要删除最后一个元素的原因。

If you want to remove a specific element you'll need to pass some information to the removeItem function about which element you want removed and then have removeItem() drop that specific element from the todos array instead of pop ping the last element.如果要删除特定元素,则需要将一些有关要删除的元素的信息传递给removeItem函数,然后让removeItem()todos数组中删除该特定元素,而不是pop最后一个元素。 One simple way to do this would be to pass the array index to the removeItem function, and then splice that index out of the todos array:一种简单的方法是将数组索引传递给removeItem函数,然后将该索引从 todos 数组中splice出来:

<li v-for="(todo, index) in todos">
  ...
  <a v-on:click="removeItem(index)">Delete</a>
</li>
removeItem: function(index) {
  this.todos.splice(index, 1);
},

Your full snippet with that change applied is below:应用了该更改的完整代码段如下:

 // components Vue.component('todoitem', { template: "<li>Test Item</li>" }) // app code var app = new Vue({ el: '#app', data: { todos: [ { text: 'Sample Item 1' }, { text: 'Sample Item 2' }, { text: 'Sample Item 3' } ], button: { text: 'Hide' }, seen: true }, methods: { addItem: function() { let item = document.getElementById("list-input").value; let error = document.getElementById("error"); if (item == "") { error.style.display = "block"; } else { app.todos.push({ text: item }); error.style.display = "none"; } }, removeItem: function(index) { this.todos.splice(index, 1); }, toggleSeen: function() { app.seen = !app.seen; app.button.text = app.seen ? 'Hide' : 'Show'; } } });
 .todo-list { list-style-type: square; } .todo-list__delete { display: none; } li:hover .todo-list__delete { display: inline-block; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script> <div id="app"> <ul class="todo-list"> <li v-for="(todo, index) in todos"> {{ todo.text }} <a v-on:click="removeItem(index)" class="todo-list__delete" href="#">Delete</a> </li> </ul> <input type="text" id="list-input"> <input type="submit" id="list-submit" v-on:click="addItem"> <span id="error" style="color: red; display: none;">Please Enter Text</span> <ul> <todoitem></todoitem> </ul> <h2 v-if="seen">SEEN</h2> <button id="hide-seen" v-on:click="toggleSeen">{{ button.text }}</button> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM