目录
解决冲突的方法:给某个状态机中变量重命名,用辅助函数mapState()。
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex是一个状态管理模式,状态机,将组件共享的数据放到状态机中统一管理,组件想拿数据可以从自己的数据模型中拿,也可以从仓库中拿,把vuex理解成一个仓库。
把A组件和B组件的数据放到Vuex中,A组件想要获取B组件数据从vuex中拿,B组件想要获取A组件的数据从Vuex拿。
使用
1、生成仓库/状态机配置对象---五个属性可选
2、生成Vuex Store构造函数的状态机---new Vuex.Store
3、注册状态机---router
4、访问状态机中的数据---$store.state.xx或鼠标触发提交突变、分发动作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入vue,引入vuex -->
<script src="./js/vue-2.6.12.js"></script>
<script src="./js/vuex-3.5.1.js"></script>
</head>
<body>
<div id="app">
<!-- 4、访问状态机中的数据 -->
{{$store.state.storeMsg}}
-------------------------------
{{$store.getters.storeMsgUpper}}
<button @click="$store.commit('changeMsg','数据修改为test')">提交突变</button>
<button @click="$store.dispatch('getMsg','terry')">分发动作</button>
</div>
<script>
// 1、生成仓库/状态机配置对象
let storeCnf = {
// 类似于组件内的data(){},在state中存放的是组件之间的共享数据
state: {
storeMsg: '状态机中的数据hello'
},
// 类似于computed属性,对state中的属性处理之后再返回,从state中派生出来的
getters: {
// 默认参数为state
storeMsgUpper(state) {
return state.storeMsg.toUpperCase()
}
},
// 突变,同步操作,唯一修改state中数据的方式
mutations: {
// 参数为state、payload,state为默认参数类似于事件中的event,payload载荷形参
changeMsg(state, payload) {
state.storeMsg = payload
}
},
// 动作,存放的是异步请求
actions: {
// 参数为sto、payload,sto是类状态机对象,payload载荷形参
// getMsg(sto, payload) {
// 将sto解构出来为{commit,dispatch,state,getters}
getMsg({commit,dispatch,state,getters}, payload) {
// console.log(sto);
// 提交突变
// sto.commit('突变事件名称','传递的数据res');
// sto.commit('changeMsg',payload);
// sto解构出来提交突变
commit('changeMsg', payload);
// 分发动作
// sto.dispatch('getMsg','larry')
}
}
};
// 2、生成Vuex Store构造函数的状态机
let store = new Vuex.Store(storeCnf);
new Vue({
el: '#app',
// 3、注册状态机
store,
data:{
},
created() {
console.log(this.$store.state, '111');
console.log(this.$store.getters, '222');
console.log(this.$store.mutations, '333');
console.log(this.$store.actions, '444');
},
methods: {
},
})
</script>
</body>
</html>
五个属性
1、State
在State中存放状态,可将状态理解为组件中的data,
只不过在state中一般存放的是组件共享的数据,而在组件内的data中一般存放组件的私有数据。
2、getters
类似于computed属性,对state中的属性处理之后再返回,从state中派生出来的
默认参数为state
3、mutations
突变,同步操作,唯一修改state中数据的方式
参数为state、payload,state为默认参数类似于事件中的event,payload载荷形参
4、actions
动作,存放的是异步请求
参数为sto、payload,sto是类状态机对象解构出来{commit,dispatch,state,getters},payload同上
提交突变:sto.commit('changMsg',res);
第一个参数是触发突变的事件名称,第二个参数是获取到的后台数据
分发动作:sto.dispatch('getAll',[])
第一个参数是分发动作的事件名称,第二个参数是要传递的数据
5、modules
模块化
辅助函数
1、mapState()
为组件创建计算属性以返回 Vuex store 中的状态。
第一个参数是可选的,可以是一个命名空间字符串。
2、mapGetters()
为组件创建计算属性以返回 getter 的返回值。
第一个参数是可选的,可以是一个命名空间字符串。
3、mapMutations()
创建组件方法提交 mutation,返回的结果是一个对象。
4、mapActions()
创建组件方法分发 action,返回的结果是一个对象。
mapState和mapGetters写在computed中,mapMutations和mapActions写在methods中
computed:{
...mapState(namespace,['storeMsg','msg1']),
...mapGetters(namespace,['storeMsgUpper'])
},
methods:{
...mapMutations(namespace,['changeMsg']),
...mapActions(namespace,['getAll'])
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入vue,引入vuex -->
<script src="./js/vue-2.6.12.js"></script>
<script src="./js/vuex-3.5.1.js"></script>
</head>
<body>
<div id="app">
<!-- 4、访问状态机中的数据 -->
{{storeMsg}}--{{storeMsg1}}
<br>
{{storeMsgUpper}}--{{storeMsgUpper1}}
<button @click="changeMsg('状态机中的数据修改为test')">提交突变</button>
<button @click="getMsg('terry')">分发动作</button>
</div>
<script>
// 辅助函数,专门用来处理状态机属性,是Vuex状态机提供的
// mapState和mapGetters写在computed中
// mapActions和mapMutations写在methods中
// 将辅助函数从状态机中解构出来
let {mapState,mapActions,mapMutations,mapGetters} = Vuex;
// 1、生成仓库/状态机配置对象
let storeCnf = {
state: {
storeMsg: '状态机中的数据hello',
storeMsg1: '状态机中的数据world'
},
getters: {
storeMsgUpper(state) {
return state.storeMsg.toUpperCase()
},
storeMsgUpper1(state) {
return state.storeMsg1.toUpperCase()
}
},
mutations: {
changeMsg(state, payload) {
state.storeMsg = payload
}
},
actions: {
getMsg({ commit, dispatch, state, getters }, payload) {
commit('changeMsg', payload);
// 分发动作
// sto.dispatch('getMsg','larry')
}
}
};
// 2、生成Vuex Store构造函数的状态机
let store = new Vuex.Store(storeCnf);
new Vue({
el: '#app',
// 3、注册状态机
store,
data: {
},
// 辅助函数
computed: {
// mapState 映射state数据 mapgetters 映射getters数据
// ...Vuex.mapState(['storeMsg', 'storeMsg1']),
// ...Vuex.mapGetters(['storeMsgUpper', 'storeMsgUpper1'])
// 将辅助函数从状态机中解构出来
...mapState(['storeMsg', 'storeMsg1']),
...mapGetters(['storeMsgUpper', 'storeMsgUpper1'])
},
methods: {
// ...Vuex.mapActions(['getMsg']),
// ...Vuex.mapMutations(['changeMsg'])
// 将辅助函数从状态机中解构出来
...mapActions(['getMsg']),
...mapMutations(['changeMsg'])
},
})
</script>
</body>
</html>
模块化
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
1、声明多个状态机/仓库
2、创建状态机对象并进行模块化导入---module
3、注册状态机
4、访问状态机中的数据
namespaced: true表示设置命名空间。
解决冲突的方法:给某个状态机中变量重命名,用辅助函数mapState()。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入vue,引入vuex -->
<script src="./js/vue-2.6.12.js"></script>
<script src="./js/vuex-3.5.1.js"></script>
</head>
<body>
<div id="app">
<!-- 4、访问状态机中的数据 -->
{{aMsg}}--{{bMsg}}--{{msg}}--{{Msg}}
</div>
<script>
let { mapState } = Vuex;
// 1、声明多个状态机/仓库
let aModule = {
// 命名空间
namespaced: true,
state: {
aMsg: 'a仓库公共的属性',
msg: 'a的仓库里面的msg'
},
// getters: {},
// mutations: {},
// actions: {}
};
let bModule = {
namespaced: true,
state: {
bMsg: 'b仓库公共的属性'
},
// getters: {},
// mutations: {},
// actions: {}
};
// 2、创建状态机对象
let store = new Vuex.Store({
// 模块化导入
modules: {
// 重命名的名字是属性名,左边是新名字
a: aModule,
b: bModule
},
// state: {},
// getters: {},
// mutations: {},
// actions: {}
});
new Vue({
el: "#app",
// 3、注册状态机
store,
data: {
msg: '我是vue实例数据模型中的数据'
},
computed: {
// ...mapState('aModule',['aMsg']),
// ...mapState('bModule',['bMsg']),
// 使用新名字(重命名)
...mapState('a',['aMsg']),
...mapState('b', ['bMsg']),
// 解决冲突
...mapState('a', {
// 第二个参数对象给仓库中的数据重命名,对象内的属性名是新名字(左边)
aMsg: 'aMsg',
Msg: 'msg'
}),
},
methods: {
}
})
</script>
</body>
</html>