创建仓库即4步走:
// 创建一个仓库,并且存放一些全局数据(四大选项) const store = new Vuex.Store({ // 全局数据 state: { todos: [] }, // 同步函数 mutations: { GETALL(state, payload){ // state.todos.push(...payload) state.todos = payload }, DEL(state, payload){ // 根据id删除state的数据 state.todos = state.todos.filter(item=>item.id != payload.id) }, ADD(state, payload) { console.log(payload) // 插入到数组中 state.todos.push(payload) }, CHANGE(state, payload){ state.todos.map(item=>{ return item.id == payload.id ? payload : item }) } }, // 异步函数 actions: { async GETALL({commit}, payload){ // 请求接口中的数据,然后存储道state的todos中 var data = await fetch("http://127.0.0.1:3000/mapList").then(data=>data.json()) // 发出commit命令,并且将数据当作载荷传递过去 commit('GETALL', data) }, async DEL({ commit }, payload) { // 向API接口发出删除请求,删除本地db.json中的数据 await fetch("http://127.0.0.1:3000/mapList/" + payload.id, { method: 'DELETE' }) // 删除全局state仓库的数据,影响视图更新 commit('DEL', payload) }, async ADD({ commit }, payload) { var data = await fetch("http://127.0.0.1:3000/mapList", { method: 'POST', headers: {'Content-type': 'application/json'}, body: JSON.stringify(payload) //只能提交字符串类型的JSON }).then(data => data.json()) // 新增数据到state中,影响视图更新 commit("ADD", data) }, async CHANGE({ commit }, payload){ var data = await fetch("http://127.0.0.1:3000/mapList/" + payload.id, { method: 'PATCH', headers: { 'Content-type': 'application/json' }, body: JSON.stringify(payload) //只能提交字符串类型的JSON }).then(data => data.json()) // 虽然实现了修改,视图也更新了,但为了可预测状态的完整性,还是写上 commit('CHANGE', data); } }, // 计算属性 getters: { yizuo(state, getters){ return state.todos.filter(item=>item.done) //返回已做的 }, weizuo(state, getters){ return state.todos.filter(item => !item.done) //返回未做的 } }, plugins: [ createLogger() ] })
vue组件中的代码:
<template> <div> <div> <el-input v-model="txt" placeholder="请输入内容" class="add"></el-input> <el-button type="primary" @click="add" icon="el-icon-circle-plus">增加</el-button> </div> <ul> <li is="TodoLi" v-for="item in todos" :item="item"></li> </ul> <p> 全部:{{$store.state.todos.length}}个代办事项-- 已做:{{$store.getters.yizuo.length}}个完成事项-- 未做:{{$store.getters.weizuo.length}}个代办事项 </p> <el-button type="primary" @click="all">查看全部</el-button> <el-button type="primary" @click="yizuo">查看已做</el-button> <el-button type="primary" @click="weizuo">查看未做</el-button> </div> </template> <script> import TodoLi from "./components/TodoLi.vue" export default { created(){ // 发出一个异步命令,触发actions this.$store.dispatch('GETALL') }, data(){ return { txt: '', state: 'all' } }, computed: { todos(){ if(this.state == 'all'){ return this.$store.state.todos }else if(this.state == 'yizuo'){ return this.$store.getters.yizuo }else if(this.state == 'weizuo'){ return this.$store.getters.weizuo } } }, methods: { add(){ if(this.txt == '') return; // 内容不为空,则发出新增的异步请求命令 this.$store.dispatch('ADD', {id: new Date()-0, title: this.txt, done: false}) this.txt = '' }, all(){ this.state = 'all' }, weizuo(){ this.state = 'weizuo' }, yizuo(){ this.state = 'yizuo' } }, components: { TodoLi } } </script> <style scoped> ul{margin: 0;padding: 0;} .add{ 300px; } </style>
vue commit发生异步(dispatch)等
<template> <li> <el-checkbox v-model="item.done" @change="changeDone(item)"/> <span v-if="!isShow" class="title" @dblclick="showInput" :class="{cur: item.done}"> {{item.title}} </span> <el-input v-if="isShow" v-model="item.title" autofocus @change="hideInput(item)"> </el-input> <el-button type="danger" icon="el-icon-delete" circle class="btn" @click="del(item.id)"> </el-button> </li> </template> <script> export default { props: ['item'], data(){ return { isShow: false } }, methods: { del(id){ this.$store.dispatch('DEL', { id }) }, showInput(){ // 双击显示input this.isShow = true }, hideInput(item){ // 失去焦点隐藏input,并且发送命令修改title this.isShow = false; this.$store.dispatch('CHANGE', item) }, changeDone(item){ this.$store.dispatch('CHANGE', item) } }, // directives: { // // 自定义组件指令,自动得到焦点 // focus: { // inserted(el){ // el.focus() // } // } // } } </script> <style scoped> li{ list-style:none; 400px; height: 40px; padding-left:10px; line-height: 40px; margin-top:10px; border-bottom: 1px solid #eee; } .el-checkbox{float: left;} .title{ /* float: left; */ 80%; font-family: "Helvetica Neue","PingFang SC","Hiragino Sans GB",Arial,sans-serif; display: inline-block; } .el-input{float: left; 200px;} .btn{float: right;} .btn button{float: left;} .cur{color:#ccc;} </style>