【问题标题】:Vue.js - click events and "this"Vue.js - 点击事件和“this”
【发布时间】:2017-10-27 16:57:02
【问题描述】:

我在 vue 中有一个待办事项列表,我正在使用 pop() 来清除/删除列表项。请参阅下面有问题的代码:

// 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>

预期的行为是,当单击删除时,它会调用 removeItem 函数,并在该函数中使用 this 删除选定的项目。然而实际发生的是它只是从底部开始删除节点。

认为问题在于this 我实际上是在引用删除链接,而不是我要删除的&lt;li&gt; 元素。所以我都尝试了:

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

还有:

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

没有运气。

this 在 Vue 中是如何工作的?

【问题讨论】:

标签: javascript vue.js vue-component


【解决方案1】:

在这种情况下,this 指的是 Vue 组件(而不是 DOM 元素)。 this.todos 是组件的 data 对象内的 todos 数组,pop 删除数组的最后一项。这就是为什么要删除最后一个元素的原因。

如果您想删除特定元素,您需要将一些信息传递给removeItem 函数,了解您要删除哪个元素,然后让removeItem()todos 数组而不是@ 中删除该特定元素987654329@ping 最后一个元素。一种简单的方法是将数组索引传递给removeItem 函数,然后将splice 该索引从 todos 数组中传递出去:

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

应用了该更改的完整 sn-p 如下:

// 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>

【讨论】:

  • 我原来选择要删除的项目的方法有问题(它会删除所有具有相同文本的项目。)我将其更改为使用数组索引。
猜你喜欢
  • 2018-12-16
  • 2017-08-21
  • 1970-01-01
  • 2017-06-16
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
  • 2019-04-01
相关资源
最近更新 更多