一、定义
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
二、安装
cnpm i vuex --save
三、使用
1、vuex的文件目录结构示例
大体上分为一个文件夹,三个js文件
当项目非常大时,如果所有的状态都集中放到一个对象中,store 对象就有可能变得相当臃肿。
为了解决这个问题,Vuex允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。
细节上modules文件夹里还有若干个js文件,这若干个js文件中的每一个对应的是各个模块的状态管理数据
2 .引入项目中
全局引入
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//存储状态数据
state:{},
mutations:{},
actions:{},
getters:{},
modules:{}
})
在main.js引入
import store from './store/index.js'
new Vue({
el:'#app',
store,
})
3、三个主要的js文件
3.1 index.js 文件中的代码示例
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
// 引入总体布局上的另外两个文件
import {state,mutations,getters} from "./mutations";
import actions from "./actions";
// 引入各个模块的状态管理数据
import menuManage from "./modules/menuManage";
import roleManage from "./modules/roleManage";
import manager from "./modules/manager";
import classify from "./modules/classify";
import shopSize from './modules/shopSize';
import banner from './modules/banner';
import goods from "./modules/goods"
export default new Vuex.Store({
state,
mutations,
actions,
getters,
modules:{ //各个模块的数据进行引入
menuManage,
roleManage,
manager,
classify,
shopSize,
banner ,
goods
}
});
3.2 actions.js 文件中的代码示例
//操控mutations.js中的changeUser方法
export default {
userActions(context,data){
// console.log(data);
context.commit("changeUser",data);//把请求头放在vuex状态管理中
},
};
3.3 mutations.js 文件中的代码示例
export const state = {
// sessionStorage来做用户信息存储
// 如果sessionStorage里有用户信息,就不用再次存储,直接使用
user: sessionStorage.getItem("user") ? JSON.parse(sessionStorage.getItem('user')): null
};
//操控state中定义的user变量
export const mutations = {
changeUser(state, data) {
state.user = data;
if(data){
sessionStorage.setItem("user",JSON.stringify(data))
}else{
sessionStorage.removeItem("user")
}
}
};
// 将数据返出去
export const getters = {
resUser(state){
return state.user;
}
};
4、各个模块中的状态管理 示例
例如 classify.js 文件中的代码
// 这是请求数据的接口
import {reqClassifyList} from "../../utils/request";
// 1、在state 中定义一个变量classifyList来存储数据
const state = {
classifyList:[],
};
// 2、在mutations 中写一个方法changeClassifyList来赋值给state
const mutations = {
changeClassifyList(state,arr){
state.classifyList = arr;// 赋值
},
};
// 2、在actions 中写一个方法classifyListActions,将请求到的数据传递给mutations 中的changeClassifyList方法
const actions = {
classifyListActions(context){
// reqClassifyList为数据请求,该传参就传参,res是请求成功时返回的数据
reqClassifyList({istree:true}).then(res=>{
context.commit("changeClassifyList",res.data.list);//对接mutations 中的changeClassifyList方法
});
},
};
// 将state中的数据返出去,在组件中接收,一会儿有代码说明
const getters = {
resClassifyList(state){
return state.classifyList;
},
};
// 将该文件中的数据导出去
//namespaced表示当前模块是否使用命名空间,如果使用的话,那么设置了namespaced属性的模块将和其它模块独立开来,调用时得指定命名空间后才可以访问得到(一会代码说明)
export default {
state,
mutations,
actions,
getters,
namespaced: true // 命名空间的名称就是文件名classify
};
5、在组件中的使用
推荐的使用方式
在组件中
<template>
<div>
<el-table
:data="tableData" // tableData是从vuex中取出的数据
style="width: 100%;margin-bottom: 20px;"
row-key="id"
border
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column prop="id" label="分类编号" sortable width="180"></el-table-column>
<el-table-column prop="catename" label="分类名称" sortable width="180"></el-table-column>
<el-table-column label="图片">
<template v-slot="p">
<img :src="$preImg + p.row.img" :alt="p.row.catename" v-if="p.row.img" />
</template>
</el-table-column>
<el-table-column prop="status" label="状态">
<template v-slot="p">
<el-button type="success" class="green" v-if="p.row.status">启 用</el-button>
<el-button type="danger" class="red" v-else>禁 用</el-button>
</template>
</el-table-column>
<el-table-column label="操作">
<template v-slot="p">
<el-button type="success" @click="edit(p.row.id)">编 辑</el-button>
<el-button type="danger" @click="del(p.row.id)">删 除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
// 引入状态管理vuex的方法
import { mapActions, mapGetters } from "vuex";
// 请求删除数据的接口
import { reqDelClassify } from "../../../utils/request";
export default {
props: ["info"],
data() {
return {
};
},
computed: {
// mapGetters传递一个json,json中可以有多个值,值中的key对接是组件使用的变量名,值中的value对接的是getters中的方法名
// tableData是一个变量名,不在data中定义,在这就是直接定义和使用
...mapGetters({
tableData: "classify/resClassifyList" //classify是命名空间的名字 resClassifyList 是classify.js文件中getters返回出来的数据
})
},
methods: {
// mapActions传递一个json,json中的可以有多个值,值中的可以对接的是组件中的事件方法名,值中的value对接的是actions中的方法名
// requestClassifyList是一个方法名,不用定义,可直接使用
...mapActions({
requestClassifyList: "classify/classifyListActions",
//classify是命名空间的名字 classifyListActions是classify.js文件中actions里的方法名,
// 这一步操作相当于将vuex中的classifyListActions方法传递给requestClassifyList,
//此时的requestClassifyList就是classifyListActions,
//使用时,classifyListActions要求传参,requestClassifyList就传参
}),
edit(id) {
this.$emit("edit", id);
this.info.showAdd = true;
},
del(id) {
this.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
// 请求删除数据
reqDelClassify({ id: id }).then(res => {
// res是请求成功返回的数据
});
// 对应vuex中中actions里的方法,如果要传参就传参
this.requestClassifyList();
})
.catch(() => {
// catch是请求失败时候执行的方法
this.$message({
type: "info",
message: "已取消删除"
});
});
}
},
mounted() {
// 请求商品分类列表
this.requestClassifyList();
}
};
</script>
<style scoped>
</style>
不推荐 但是也能达到效果
现在说的方法是直接在组件中使用this.$store
来操控vuex,
不推荐原因是:vue中进行数据操控是为了方便数据追踪,出错时容易查找问题,
(1)关于state
//组件中访问:
// 直接使用this.$store.state来渲染
<div>name:{{this.$store.state.name}}</div>
<div>age:{{this.$store.state.age}}</div>
(2)关于mutations
// vuex中
mutations:{
// state是系统自动注入的参数
changeName(state,newName){
state.name = newName;
},
changeAge(state,newAge){
state.age = newAge
}
}
<!-- 对接组件使用方式 -->
<!-- 修改状态层数据 -->
<!-- 通过commit提交对接store中mutations的方法 -->
<!-- 方式一 -->
<button @click="$store.commit('changeName','梁小胖')">梁小胖</button>
<button @click="$store.commit('changeAge',50)">50</button>
(3)关于actions
// vuex中
// 对接组件中的操作方法
actions:{
// 参数 context是系统自动注入
nameActions(context,name){
context.commit('changeName',name)
},
ageActions(context,age){
context.commit('changeAge',age)
}
}
组件中对接方式
<!-- 通过dispatch对接store中actions的方法 -->
<!-- 方式二 -->
<button @click="$store.dispatch('nameActions','赵珊珊')">赵珊珊</button>
<button @click="$store.dispatch('ageActions',18)">18</button>
好了:总结到此结束,如果你不知道vuex之间各个属性怎么运作的,查看以下链接
https://blog.csdn.net/TTianYe/article/details/115288814?spm=1001.2014.3001.5501
欢迎留言讨论