介绍
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
原先数据需要保存到各自vue实例对象的data中,当使用vuex之后,就可以将data中的数据集中管理到vuex中。
vue - data
{
customer:{}
}
-
交互:
双向数据绑定
渲染
事件绑定,事件处理 -
数据维护 (转交-> vuex)
loadData
axios.get()
vuex - state -
数据维护【状态】
Customer.vue
{
customers:[],
visible:false,
}
Category.vue
{
categories:[],
visible:false
}
...
核心概念
1. state 状态,data,用于存储状态
state:{
customers:[]
}
- getter 获取器,类似于computed,从store 中的 state 中派生出一些状态
getters:{
customersSize:function(){
return customers.length;
},
customersFilter(){
}
}
- mutation 突变,是vuex中唯一可以修改state值的机制,并且这种修改是同步的,不允许包含异步代码
mutations:{
refreshCustomers(state,customers){
state.customers = customers;
}
}
- action 动作,是vuex中唯一可以包含异步【异步操作的同步化】操作的机制,但是,action不能直接修改state中的值,但是可以通过提交突变的方式修改state中的值
actions:{
async findAllCutomers(context){
let response = await axios.get();
context.commit("refreshCustomers",response.data.data)
}
}
深入理解状态机
0 实例化
let store = new Vuex.Store({
state:{},
getters:{},
mutations:{},
actions:{}
})
- state
1) 作用
维护状态,customers、visible…
2) 定义
state:{
customers:[],
visible:false
}
3)使用
1. 通过状态机实例对象直接访问
store.state.customers
2. 如何在vue实例中访问(通过计算属性映射)
new Vue({
el:"",
store, //注入store
data:{},
computed:{
customers:function(){
return this.$store.state.customers;
}
}
})
- mutation
1) 作用
唯一修改state值的机制,并且只能是同步操作
2) 定义
state:{
customers:[]
}
mutations:{
refreshCustomers(state,customers){
}
}
state是vuex实例化并且传递给突变,customers属于该突变一个载荷对象(参数)
3) 使用
store.commit("refreshCustomers",[1,2,3])
- action
1) 作用
封装异步操作,不能直接更新state,必须借助mutation来进行更新
2) 定义
actions:{
async findAllCustomers(context){
let response = await axios.get();
context.commit("refreshCustomers",response.data.data)
},
//payload为id
async deleteCustomerById(context,payload){
let response = await axios.get("",payload);
context.dispatch("findAllCustomers")
}
}
context是一个与store对象解构相似的对象,包含了commit、dispatch、getters、state
(3) 使用
store.dispatch(actionName,payload)
模块化
let customer = {
namespaced:true,
state:{
list:[],
visible:false
},
getters:{
},
mutations:{
},
actions:{
}
},
let category = {
namespaced:true,
state:{
list:[],
visible:false
},
getters:{
},
mutations:{
},
actions:{
}
}
let store = new Vuex.Store({
modules:{
customer,
category
}
})
new Vue({
computed:{
...Vuex.mapState("customer",["list"])
}
})
实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>顾客管理</title>
<!-- vue + vuex + axios + lodash -->
<script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.js"></script>
<script src="https://cdn.bootcss.com/lodash.js/4.17.15/lodash.js"></script>
<!-- 导入vue -->
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.1.1/vuex.js"></script>
<!-- jquery $.param-->
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<div id="app">
<h2>顾客管理</h2>
<!-- 按钮 -->
<div>
<button @click="toAddHandler">添加</button>
<button @click="batchDeleteHandler">批量删除</button>
</div>
<!-- 表单 -->
<div v-show="visible">
{{customer}}
<form action="" @submit.prevent="submitHandler">
姓名 <input type="text" v-model="customer.realname"/>
手机号 <input type="text" v-model="customer.telephone"/>
<input type="submit" value="提交">
<button @click.prevent="closeModal">关闭</button>
</form>
</div>
<!-- 表格 -->
<div>
{{customerSize}}
<table>
<thead>
<tr>
<th>编号</th>
<th>id</th>
<th>姓名</th>
<th>手机号</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in customers">
<td><input type="checkbox" :value="item.id" v-model="ids"> </td>
<td>{{item.id}} </td>
<td>{{item.realname}} </td>
<td>{{item.telephone}}</td>
<td>{{item.status}}</td>
<td>
<a href="" @click.prevent="deleteHandler(item.id)">删除</a>
<a href="" @click.prevent="editHandler(item)">修改</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<script>
axios.defaults.baseURL = "http://134.175.100.63:6677"
// 状态机
let store = new Vuex.Store({
state:{
customers:[],
visible:false
},
getters:{
customerSize(state){
return state.customers.length;
},
orderCustomer:(state)=>{
return function(flag){
state.customers.sort((a,b)=>{
if(a[flag] > b[flag]){
return -1;
} else {
return 1;
}
})
return state.customers;
}
}
},
mutations:{
showModal(state){
state.visible = true;
},
closeModal(state){
state.visible = false;
},
refreshCustomers(state,customers){
state.customers = customers;
}
},
actions:{
async batchDeleteCustomer(context,ids){
// 1. 批量删除
let response = await axios({
method:"post",
url:"/customer/batchDelete",
data:$.param({ids},true),
headers:{
"Content-Type":"application/x-www-form-urlencoded"
}
});
// 2. 分发
context.dispatch("findAllCustomers");
// 3. 返回结果
return response;
},
async deleteCustomerById(context,id){
let response = await axios.get("/customer/deleteById?id="+id);
context.dispatch("findAllCustomers");
return response;
},
async findAllCustomers(context){
// 1. ajax查询
let response = await axios.get("/customer/findAll");
// 2. 将查询结果更新到state中
context.commit("refreshCustomers",response.data.data);
},
// payload 顾客信息
async saveOrUpdateCustomer({commit,dispatch},payload){
// 1. 保存或更新
let response = await axios({
method:"post",
url:"/customer/saveOrUpdate",
data:$.param(payload),
headers:{
"Content-Type":"application/x-www-form-urlencoded"
}
})
// 2. 刷新页面
dispatch("findAllCustomers");
// 3. 关闭模态框
commit("closeModal");
// 4. 提示
return response;
//异步函数提交后,拿到承诺对象
}
}
})
new Vue({
el:"#app",
data:{
customer:{},
ids:[]
},
store,
computed:{
// 映射 store->vue
/*
customers:function(){
return this.$store.state.customers;
},
visible:function(){
return this.$store.state.visible;
}*/
...Vuex.mapState(["customers","visible"]),
...Vuex.mapGetters(["orderCustomer","customerSize"])
},
created(){
this.findAllCustomers();
},
methods:{
// 映射 store -> vue
/*
showModal(){
return this.$store.commit("showModal");
},
closeModal(){
return this.$store.commit("closeModal");
},
*/
...Vuex.mapMutations(["showModal","closeModal"]),
...Vuex.mapActions(["findAllCustomers","saveOrUpdateCustomer","deleteCustomerById","batchDeleteCustomer"]),
/*
findAllCustomers(){
return this.$store.dispatch("findAllCustomers")
},
saveOrUpdateCustomer(customer){
return this.$store.dispatch("saveOrUpdateCustomer",customer)
},
deleteCustomerById(id){
return this.$store.dispatch("deleteCustomerById",id)
},
batchDeleteCustomer(ids){
return this.$store.dispatch("batchDeleteCustomer",ids)
},
*/
// 普通方法
toAddHandler(){
// 1. 重置表单
this.customer = {};
// 2. 显示模态框
this.showModal();
},
submitHandler(){
let promise = this.saveOrUpdateCustomer(this.customer)
promise.then((response)=>{
// promise为action函数的返回值,异步函数的返回值就是promise的then回调函数的参数
alert(response.data.message);
})
},
editHandler(row){
this.customer = row;
this.showModal();
},
deleteHandler(id){
this.deleteCustomerById(id)
.then((response)=>{
alert(response.data.message);
})
},
batchDeleteHandler(){
this.batchDeleteCustomer(this.ids)
.then((response)=>{
alert(response.data.message);
})
}
}
})
</script>
</body>
</html>