vuex入门

优势

  • 集中管理数据,易于后期开发和维护
  • 高效的实现组件之间的数据共享,提高开发效率
  • vuex中数据都是响应式的,实时保持页面同步

哪些数据适合存储到Vuex中

只有组件之间需要共享的数据,才有必要存储到Vuex中

Vuex核心概念

State

提供唯一的公共数据源

const store = new Vuex.store({
   state: {
       count: 0
  }
})

组件中访问State数据

  • 第一种方式:this.$store.state.全局数据名

  • 第二种方式:按需导入import {mapState} from 'vuex',通过mapState函数,将当前组件需要的全局数据映射为当前组件的computed计算属性

    computed: {
       ...mapState(['count'])
    }
    

Mutation

用于变更store中的数据

  • 只能通过mutation变更Store数据,不可以直接操作Store中的数据
  • 可以集中监控所有数据变化

在vuex中定义方法

const store = new Vuex.store({
     mutations: {
       add(state) {
         state.count++
      }
    }
})

方法一:通过this.$store.commit方法触发vuex中的方法

methods: {
   btnHandle1() {
       this.$store.commit('add')
  }
}

可以在触发mutation的时候传递参数

const store = new Vuex.store({
 mutations: {
   addN(state, step) {
     state.count += step
  }
}
})
······
btnHandle2() {
   this.$store.commit('add', 3)
}

方法二:从Vuex中按需导入mapMutations函数,将需要的mapMutations函数映射为当前组建的methods方法

import {mapMutations} from 'vuex'
···
methods: {
   ...mapMutations(['sub']),
       Handle() {
       this.sub()
  }
}

带参数

methods: {
   ...mapMutations(['subN']),
       Handle2() {
       this.subN(3)
  }
}

mutation函数中不可以执行异步操作

Action

用于处理异步任务,Action 提交的是 mutation,而不是直接变更状态

const store = new Vuex.Store({
     state: {
       count: 0
    },
     mutations: {
       add (state) {
         state.count++
      }
    },
     actions: {
        addAsync(context, step) {
          setTimeout(() => {
               context.commit('add', step)
          },1000)
        }
    }
})

方法一:通过 $store.dispatch()触发Action

btnHandle3() {
   this.$store.dispatch('addAsync')
}

携带参数

addAsyncN(context, step) {
   setTimeout(() => {
       context.commit('addN', step)
  },1000)
}
······
btnHandle4() {
   this.$store.dispatch('addAsyncN', 3)
}

方法二:从vuex中按需导入mapActions函数,将需要的actions函数映射为组建的methods

import {mapActions} from 'vuex'
······
methods: {
   ...mapActions(['subAsync']),
       Handle3() {
       this.subAsync()
    }
}

携带参数

methods: {
   ...mapActions(['subAsyncN']),
       Handle4() {
       this.subAsyncN(3)
  }
}

Getter

用于对Store中的数据进行加工处理形成新的数据,不会修改原有数据

  • 对Store中的数据进行加工处理形成新的数据,类似于Vue中的计算属性
  • Store中的数据发生变化,Getter的数据也会跟着改变

定义getter

 getters: {
   showNum(state) {
     return '当前最新数量是【' + state.count + '】'
  }
}

获取getter

方法一:通过this.$store.getters.getter的方法名

this.$store.getters.showNum

方法二:按需导入mapGetters函数,通过mapGetters函数,将当前组件需要的全局数据映射为当前组件的computed计算属性

import {mapGetters} from 'vuex'
······
computed: {
   ...mapGetters(['showNum'])
},

Vuex模块化管理

随着功能和数据不断增加,store会越来越臃肿,把不同的功能单独拆分处理,可以方便管理

└── store
  └── index.js	# 总的store
  └── modules    
  └── modulesA.js	# 模块A    
  └── modulesB.js	# 模块B  ·
  # 其他模块

规模较小的可以将不同的核心放在一个模块js中,分多了反而不方便

user.js

const state = {}
const actions = {}
_______________
export defult {  
    namespaced: true,  
    state,
    actions, 
}

index.js

import moduleA from './modules/modulesA'
___________
modules: {  
    moduleA
}

Vuex模块化管理调用

不同功能划分模块之后引入数据的方式略有改变

state

方法一:

this.$store.state.moduleA.key2,在原来直接引入数据的基础上,添加了模块名

方法二:

computed: {
   ...mapState({
       key: state => state.moduleA.key1
  })
-------------------
   ...mapState('moduleA', {
       key: "key1"
  }),
},

将模块中的key1赋值给计算属性key,两种方法结果是一样的

mutations

方法一:

this.$store.commit('moduleA/changeValue'),在原来直接调用方法名的基础之上添加模块名

方法二:

methods: {
   ...mapMutations('moduleA',['changeValue']),
       handle() {
       this.changeValue()
  }
}

在引入方法之前添加模块名

actions

同mutataions

方法一:

this.$store.dispatch('moduleA/changeAsync')

方法二:

methods: {
       ...mapActions('moduleA', ['changeAsync']),
       handle() {
       this.changeAsync()
  }
}

getters

方法一

computed: {
   ...mapGetters('moduleA',{
       dKey: "detailValue"
  })
},

方法二

-

this.$store.getters['moduleA/getMethods']

Vuex状态管理

image-20200818190240074

组件通过调用actions触发mutations来修改state,state经过getters包装之后显示到组件;

组件不能直接修改state,只让mutation修改state


前端小白