TodoItem.vue 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <template>
  2. <li class="todo" :class="{ completed: todo.done, editing }">
  3. <div class="view">
  4. <input class="toggle"
  5. type="checkbox"
  6. :checked="todo.done"
  7. @change="toggleTodo(todo)">
  8. <label v-text="todo.text" @dblclick="editing = true"></label>
  9. <button class="destroy" @click="removeTodo(todo)"></button>
  10. </div>
  11. <input class="edit"
  12. v-show="editing"
  13. :value="todo.text"
  14. ref="input"
  15. @keyup.enter="doneEdit"
  16. @keyup.esc="cancelEdit"
  17. @blur="doneEdit">
  18. </li>
  19. </template>
  20. <script>
  21. import { nextTick } from 'vue'
  22. import { mapActions } from 'vuex'
  23. export default {
  24. name: 'Todo',
  25. props: ['todo'],
  26. data () {
  27. return {
  28. editing: false
  29. }
  30. },
  31. directives: {
  32. focus (el, { value }, { context }) {
  33. if (value) {
  34. context.$nextTick(() => {
  35. el.focus()
  36. })
  37. }
  38. }
  39. },
  40. watch: {
  41. editing (v) {
  42. v && nextTick(() => { this.$refs.input.focus() })
  43. }
  44. },
  45. methods: {
  46. ...mapActions([
  47. 'editTodo',
  48. 'toggleTodo',
  49. 'removeTodo'
  50. ]),
  51. doneEdit (e) {
  52. const value = e.target.value.trim()
  53. const { todo } = this
  54. if (!value) {
  55. this.removeTodo(todo)
  56. } else if (this.editing) {
  57. this.editTodo({
  58. todo,
  59. value
  60. })
  61. this.editing = false
  62. }
  63. },
  64. cancelEdit (e) {
  65. e.target.value = this.todo.text
  66. this.editing = false
  67. }
  68. }
  69. }
  70. </script>