Vuex全局状态管理器
官方文档:https://vuex.vuejs.org/zh/guide/modules.html
使用步骤:
*引入vuex
1:下载vuex模块
2:新建一个store文件夹(这个不是必须的),并在文件夹下新建store.js文件,文件中引入我们的vue和vuex
3:引入之后用Vue.use进行引用。
*注册全局
在main.js引入store,然后 , 在实例化 Vue对象时加入 store 对象 :
在组件中,就可以通过this.$store 来使用store实例
应用场景
单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车
理解:
Vuex 是一个专为 Vue.js 组件通信开发的状态管理模式,适用于中大型的开发项目.
规则:
应用层级的状态应该集中到单个 store 对象中。
组件不允许直接修改属于 store 实例的 state
提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
异步逻辑都应该封装到 action 里面。
getters 可以对State进行计算操作,它就是Store的计算属性,可以复用;
但如果如果一个状态只在一个组件内使用,是可以不用gettersvuex的
刷新数据丢失:
原因:
tore里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值。
解决办法:
使用store.js(数据存储插件),存储数据到本地浏览器
store.set 存储 store.get 获取 store.remove 删除
属性
有五种,分别是 State、 Getter、Mutation 、Action、 Module
state就是数据源存放地,getters 可以对State进行计算操作,是Store的计算属性
初始化(单库模式)
cnpm i vuex -S
store>index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex); //this.$store.state
//向外暴露
export default new Vuex.Store({
state:{ //全局属性变量
msg:"xxx"
},
mutations:{ //全局操作state的方法
test(state,data){} //第一个参数固定state,传参从第二个开始取
},
getters:{
count(state){} //Vuex属性计算
}
actions:{getIndexData(context,data){}} //异步函数,发送通用接口
//context
//context.state context.getters context.commit context.dispatch
})
import store from '@/core/store'
//在 入口文件 引入
new Vue({
store,
}).$mount('#app')
组件操作
$store.state.xxx
$stroe.getters.xxx//当属性变量使用
//在函数内部 加 this.$store
mutations -> $store.commit("fnName",{xxxx:"xxxx"})//只能传一个参数
actions -> $store.dispacth("fnName",{xxx:"xxx"})
暴露Vuex方式
//组件使用
<template>
<div>
<h1>Two</h1>
<h1>名称:{{name}}</h1>
<p>价格:{{price}}</p>
<p>总价:{{count}}</p>
<p>数量:{{num}}</p>
<button @click="add">add</button>
<button @click="getTestData">test</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapGetters, mapActions } from "vuex";
export default {
computed: {
//属性 state
...mapState(["name", "num", "price"]),
//属性计算 getters
...mapGetters(["count"])
},
methods: {
//mutations
...mapMutations(["add"]),
//actions
...mapActions(["getTestData"]),
}
}
</script>
多模块形式
//indexModel.js
var store={
namespaced:true, //多模块暴露,当做命名空间,必须加这个字段
state:{
msg:"lala"
},
mutations:{
setName(state){
state.msg="hyduan"
}
},
getters:{},
actions:{}
}
export default store;
//listModel.js
var store={
namespaced:true,
state:{
msg:"lala"
},
mutations:{
setName(state){
state.msg="hyduan"
}
},
getters:{},
actions:{}
}
export default store;
//store/index.js
import Vue from "vue";
import Vuex from "vuex";
import indexModel from "./indexModel"
import listModel from "./listModel"
Vue.use(Vuex);
export default new Vuex.Store({
modules:{
indexModel,
listModel
}
})
多模块视图使用
$store.state.indexModel.msg
$store.getters.indexModel.count
$store.commit('setName')
$store.dispatch('getTestData')
//可以调用所有数据模块的方法,如果重名都调用都执行
多模块Vuex暴露使用
<script>
import { mapState, mapMutations, mapGetters, mapActions } from "vuex";
export default {
mounted(){
},
computed:{
...mapState("indexModel",["msg"]),
...mapGetters("indexModel",["count"]),
},
methods:{
...mapMutations("indexModel",["setName"]),
...mapActions("indexModel",["getTestData"]),
}
};
</script>