创建仓库即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{
width: 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;
width: 400px;
height: 40px;
padding-left:10px;
line-height: 40px;
margin-top:10px;
border-bottom: 1px solid #eee;
}
.el-checkbox{float: left;}
.title{
/* float: left; */
width: 80%;
font-family: "Helvetica Neue","PingFang SC","Hiragino Sans GB",Arial,sans-serif;
display: inline-block;
}
.el-input{float: left;width: 200px;}
.btn{float: right;}
.btn button{float: left;}
.cur{color:#ccc;}
</style>