代码
main部分
index.html
vue_demo
src/base.css
body { background: #fff;}.btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(225, 225, 225, 0.2), 0 1px 2px rgba(0, 0, 0,0.15); border-radius: 4px;}.btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f;}.btn-danger:hover { color: #fff; background-color: #bd362f;}.btn:focus { outline: none;}
src/main.js
/** * Created by infaa on 2018/9/19. */import Vue from 'vue'import App from './components/App'import store from './store'import './base.css'/* eslint-disable no-new */new Vue({ el: '#app', render: h => h(App), store})
工具部分
src/util/storageUtil.js
/** * Created by infaa on 2018/9/20. */const TODO_KEY = 'todos_key'export default { saveTodos (value) { window.localStorage.setItem(TODO_KEY, JSON.stringify(value)) }, readTodos () { return JSON.parse(window.localStorage.getItem(TODO_KEY) || '[]') }}
store 部分 (vuex)
src/store/action.js
/** * Created by infaa on 2018/9/22. */import {ADD_TODO, DELETE_TODO, SELECT_ALL_TODOS, CLEAR_ALL_COMPLETED, RECEIVE_TODOS} from './mutation-types'import storeageUtil from '../util/storageUtil'export default { addTodo ({commit}, todo) { commit(ADD_TODO, {todo}) }, deleteTodo ({commit}, index) { commit(DELETE_TODO, {index}) }, selectAllTodos ({commit}, check) { commit(SELECT_ALL_TODOS, {check}) }, clearALLCompleted ({commit}) { commit(CLEAR_ALL_COMPLETED) }, reqTodos ({commit}) { // 模拟异步获取延迟1秒 setTimeout(() => { const todos = storeageUtil.readTodos() commit(RECEIVE_TODOS, todos) }, 1000) }}
src/store/getters.js
/** * Created by infaa on 2018/9/22. */export default { totalCount (state) { return state.todos.length }, completeCount (state) { return state.todos.reduce((preTotal, todo) => { return preTotal + (todo.complete ? 1 : 0) }, 0) }, isAllSelected (state, getters) { return getters.totalCount === getters.completeCount && state.todos.length > 0 }}
src/store/index.js
/** * Created by infaa on 2018/9/22. */import Vue from 'vue'import Vuex from 'vuex'import state from './state'import mutations from './mutations'import actions from './actions'import getters from './getters'Vue.use(Vuex)/* eslint-disable new-cap */export default new Vuex.Store({ state, mutations, actions, getters})
src/store/mutation-types.js
/** * Created by infaa on 2018/9/22. * mutation 名称常量 */export const ADD_TODO = 'add_todo'export const DELETE_TODO = 'delete_todo'export const SELECT_ALL_TODOS = 'select_all_todos'export const CLEAR_ALL_COMPLETED = 'clear_all_completed'export const RECEIVE_TODOS = 'receive_todos' // 接收todos
src/store/mutation.js
/** * Created by infaa on 2018/9/22. */import {ADD_TODO, DELETE_TODO, SELECT_ALL_TODOS, CLEAR_ALL_COMPLETED, RECEIVE_TODOS} from './mutation-types'export default { [ADD_TODO] (state, {todo}) { state.todos.unshift(todo) }, [DELETE_TODO] (state, {index}) { state.todos.splice(index, 1) }, [SELECT_ALL_TODOS] (state, {check}) { state.todos.forEach(todo => (todo.complete = check)) }, [CLEAR_ALL_COMPLETED] (state) { state.todos = state.todos.filter(todo => (!todo.complete)) }, [RECEIVE_TODOS] (state, todos) { state.todos = todos }}
src/store/state.js
/** * Created by infaa on 2018/9/22. */export default { todos: []}
组件部分
components/App.vue
components/TodoFooter.vue
components/TodoHeader.vue
components/TodoItem.vue
components/TodoList.vue