定义
专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应 用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方 式,且适用于任意组件间通信。
应用场景
多个组件应用与同一个状态,多个组件变更同一状态。
store创建
定义
概念:每一个Vuex应用的核心就是Store(仓库),我们可以说Store是一个容器,Store里面的状态与单纯的全局变量是不一样的,无法直接改变Store中的状态。想要改变状态需通过mutation去修改。
结构
创建文件夹store与src根目录下,建立index.js。需包含actions,mutations,state结构如下:
-
- // 引入vue
- import Vue from 'vue'
-
- // 引入vuex
- import Vuex from 'vuex'
-
- // 应用vue插件
- Vue.use(Vuex)
-
- // actions响应组件中的动作
- const actions = {
- }
-
- // mutations操作数据state
- const mutations = {
-
- }
-
-
- // 准备state存储数据
- const state = {
- //状态对象
- }
-
- // 创建store并导出
- const store = new Vuex.Store({
- actions,
- mutations,
- state,
- })
- //默认导出store
- export default store
引入store
在main.js中引入store,全局组件都可以使用vuex。
- import store from './store'
-
- new Vue({
- render: h => h(App),
- store,
- // 安装全局事件总线
- beforeCreate(){
- Vue.prototype.$bus = this
- }
- }).$mount('#app')
状态的核心概念
state
state是状态数据,可以通过this.$store.state来直接获取状态,也可以利用vuex提供的mapState辅助函数将state映射到计算属性(computed)中去。
代码示例:
- const state = {
- sum:0,
- realname:'张三',
- age:19
- }
插值引用:{{$store.state.sum}}
actions
Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。
actions响应组件中的动作
context 上下文,value组件传递过来的值
可以包含定时器,ajax代码,有业务逻辑使用action,无业务逻辑直接使用mutations
- const actions = {
-
- sumwait(context,value){
- setTimeout(()=>{
- context.commit('JIA',value);
- },2000)
- }
- }
在组件中使用: $store.dispatch('对应的 action 回调名') 触发。示范:
this.$store.dispatch('sumwait',1)// 'sumwait' 为action的动作,1为触发的值
mutations
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。
代码案例:
- const mutations = {
-
- JIA(state,value){
- state.sum = state.sum+value;
- },
- JIAN(state,value){
- state.sum = state.sum-value;
- },
-
- }
组件中触发:this.$store.commit('JIA',this.num);
此时的mutations 无业务逻辑,就是更改状态。
getters
有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数,也就是对状态在加工:
代码案例:
- const getters = {
- bigNum(state){
- return state.sum*10
- }
- }
组件中调用数据:{{$store.getters.bigNum}}
数据映射(mapState和mapGetters)
mapState(mapGetters)生成计算属性,从state中读取状态(对象形式)
案例代码:
- computed: {
- // mapState生成计算属性,从state中读取状态(对象形式)
- // ...mapState({realname:'realname',age:'age'})
- //数组形式
- ...mapState(['realname','age']),
- ...mapGetters(['bigNum'])
- },
当前组件读取:{{realname}}
数据映射(mapMutations和mapActions)
借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
- methods: {
- ...mapMutations({increment:'JIA',decrement:'JIAN'}),//对象形式
- // ...mapMutations([‘increment’,’decrement’]),//数组形式,注意store需要有同名的mutations
- }
传值需要:
Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割在模块中使用:namespaced: true, 命名空间,添加之后,当前模块下的标识符可以和其它模块相同,用于解决不同模块的命名冲突问题
代码实例:
- const countOptions = {
- namespaced:true,
- state:{
- sum:0,
- realname:'张三',
- age:19,
- },
- actions:{
- sumwait(context,value){
- setTimeout(()=>{
- context.commit('JIA',value);
- },2000)
- }
- },
- mutations:{
- JIA(state,value){
- state.sum = state.sum+value;
- },
- JIAN(state,value){
- state.sum = state.sum-value;
- },
- },
- getters:{
- bigNum(state){
- return state.sum*10
- }
- }
-
-
- }
-
- const store = new Vuex.Store({
- modules:{
- countOptions
- }
- })
-
- 组件调用(加上命名空间):
-
- computed: {
-
- ...mapState('countOptions',['realname','age','sum']),
- ...mapGetters('countOptions',['bigNum'])
- },
- methods: {
-
- ...mapMutations('countOptions',{jia:'JIA',difference:'JIAN'}),
- sumwait(){
- this.$store.dispatch('countOptions/sumwait',this.num)
- }
- },