App.vue 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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({ done: !allChecked })">
  19. <label for="toggle-all"></label>
  20. <ul class="todo-list">
  21. <todo v-for="(todo, index) in filteredTodos" :key="index" :todo="todo"></todo>
  22. </ul>
  23. </section>
  24. <!-- footer -->
  25. <footer class="footer" v-show="todos.length">
  26. <span class="todo-count">
  27. <strong>{{ remaining }}</strong>
  28. {{ remaining | pluralize('item') }} left
  29. </span>
  30. <ul class="filters">
  31. <li v-for="(val, key) in filters">
  32. <a :href="'#/' + key"
  33. :class="{ selected: visibility === key }"
  34. @click="visibility = key">{{ key | capitalize }}</a>
  35. </li>
  36. </ul>
  37. <button class="clear-completed"
  38. v-show="todos.length > remaining"
  39. @click="clearCompleted">
  40. Clear completed
  41. </button>
  42. </footer>
  43. </section>
  44. </template>
  45. <script>
  46. import { mapMutations } from 'vuex'
  47. import Todo from './Todo.vue'
  48. const filters = {
  49. all: todos => todos,
  50. active: todos => todos.filter(todo => !todo.done),
  51. completed: todos => todos.filter(todo => todo.done)
  52. }
  53. export default {
  54. components: { Todo },
  55. data () {
  56. return {
  57. visibility: 'all',
  58. filters: filters
  59. }
  60. },
  61. computed: {
  62. todos () {
  63. return this.$store.state.todos
  64. },
  65. allChecked () {
  66. return this.todos.every(todo => todo.done)
  67. },
  68. filteredTodos () {
  69. return filters[this.visibility](this.todos)
  70. },
  71. remaining () {
  72. return this.todos.filter(todo => !todo.done).length
  73. }
  74. },
  75. methods: {
  76. addTodo (e) {
  77. var text = e.target.value
  78. if (text.trim()) {
  79. this.$store.commit('addTodo', { text })
  80. }
  81. e.target.value = ''
  82. },
  83. ...mapMutations([
  84. 'toggleAll',
  85. 'clearCompleted'
  86. ])
  87. },
  88. filters: {
  89. pluralize: (n, w) => n === 1 ? w : (w + 's'),
  90. capitalize: s => s.charAt(0).toUpperCase() + s.slice(1)
  91. }
  92. }
  93. </script>