1
0

App.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <style src="todomvc-app-css/index.css"></style>
  2. <template>
  3. <section class="todoapp">
  4. <!-- header -->
  5. <header class="header">
  6. <h1>todos</h1>
  7. <input class="new-todo"
  8. autofocus
  9. autocomplete="off"
  10. placeholder="What needs to be done?"
  11. @keyup.enter="addTodo">
  12. </header>
  13. <!-- main section -->
  14. <section class="main" v-show="todos.length">
  15. <input class="toggle-all" id="toggle-all"
  16. type="checkbox"
  17. :checked="allChecked"
  18. @change="toggleAll(!allChecked)">
  19. <label for="toggle-all"></label>
  20. <ul class="todo-list">
  21. <TodoItem
  22. v-for="(todo, index) in filteredTodos"
  23. :key="index"
  24. :todo="todo"
  25. />
  26. </ul>
  27. </section>
  28. <!-- footer -->
  29. <footer class="footer" v-show="todos.length">
  30. <span class="todo-count">
  31. <strong>{{ remaining }}</strong>
  32. {{ pluralize(remaining, 'item') }} left
  33. </span>
  34. <ul class="filters">
  35. <li v-for="(val, key) in filters">
  36. <a :href="'#/' + key"
  37. :class="{ selected: visibility === key }"
  38. @click="visibility = key">{{ capitalize(key) }}</a>
  39. </li>
  40. </ul>
  41. <button class="clear-completed"
  42. v-show="todos.length > remaining"
  43. @click="clearCompleted">
  44. Clear completed
  45. </button>
  46. </footer>
  47. </section>
  48. </template>
  49. <script>
  50. import { ref, computed } from 'vue'
  51. import { useStore } from 'vuex'
  52. import TodoItem from './TodoItem.vue'
  53. const filters = {
  54. all: todos => todos,
  55. active: todos => todos.filter(todo => !todo.done),
  56. completed: todos => todos.filter(todo => todo.done)
  57. }
  58. export default {
  59. components: { TodoItem },
  60. setup () {
  61. const visibility = ref('all')
  62. const store = useStore()
  63. const todos = computed(() => store.state.todos)
  64. const allChecked = computed(() => todos.value.every(todo => todo.done))
  65. const filteredTodos = computed(() => filters[visibility.value](todos.value))
  66. const remaining = computed(() => todos.value.filter(todo => !todo.done).length)
  67. const toggleAll = (done) => store.dispatch('toggleAll', done)
  68. const clearCompleted = () => store.dispatch('clearCompleted')
  69. function addTodo (e) {
  70. const text = e.target.value
  71. if (text.trim()) {
  72. store.dispatch('addTodo', text)
  73. }
  74. e.target.value = ''
  75. }
  76. const pluralize = (n, w) => n === 1 ? w : (w + 's')
  77. const capitalize = s => s.charAt(0).toUpperCase() + s.slice(1)
  78. return {
  79. visibility,
  80. filters,
  81. todos,
  82. allChecked,
  83. filteredTodos,
  84. remaining,
  85. addTodo,
  86. clearCompleted,
  87. toggleAll,
  88. pluralize,
  89. capitalize
  90. }
  91. }
  92. }
  93. </script>