App.vue 2.3 KB

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