刚入坑不久,如有不对的地方,还请留言指正
一、Vuex
一种状态管理模式(或者说是一种数据共享模式)
- 引入Vuex方式:
//CDN方式直接引入
<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>
//NPM 引入
npm install vuex --save
- 安装完成后,项目引用方式:
//main.js中引入,即将vuex定义为全局变量
import Vuex from 'vuex'
Vue.use(Vuex)
二、Vue获取Vuex状态
通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。
const app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store,
template: '<App/>'
})
三、store结构
store
├── index.js # 我们组装模块并导出 store 的地方
├── state # 跟状态 只读
├── state_a # 变量a
└── state_b # 变量b
├── getters #暴露注册的Getters 只读
├── getters_a # 变量a
└── getters_b # 变量b
├── mutations
├── mutations_a # 变量a
└── mutations_b # 变量b
├── actions
├── actions_a # 变量a
└── actions_b # 变量b
└── modules
├── modules_a # 模块a
└── modules_b # 模块b
文件modules_a.js
const state = {//相当于自定义组件中的data
state_a:true,
state_b:true
}
const getters = {//相当于自定义组件中的computed
getters_a(){
return state.state_a
},
getters_b(){
return state.state_b
}
}
const mutations = {
//相当于自定义组件中的methods,只能做同步的操作,对state中的数据进行修改
mutations_a(state,data){
state.state_a=data
},
mutations_b(state, data) {
state.state_b=data;
}
}
const actions = {
//异步操作,例如ajax请求
//使用commit 触发 mutations
actions_a(context) {
context.commit('mutations_a')
},
// 可以异步
actions_b(context){
setTimeout(() => {
context.commit('mutations_b')
}, 1000)
}
// ES2015 的 参数解构 (opens new window) 来简化代码
actions_b({ commit }){
setTimeout(() => {
commit('mutations_b')
}, 1000)
}
}
export default {
state,
getters,
mutations,
actions
}
文件Index.js
import Vue from 'vue'
import Vuex from 'vuex'
import modules_a from './modules/modules_a
Vue.use(Vuex);
export default new Vuex.Store({
modules:{
modules_a,
modules_b
}
});
四、模块使用
1. State 访问方式
直接访问方式:this.$store.state.模块名.state变量
//直接访问方式
this.$store.state.modules_a.state_a
mapState辅助函数方式 :
方式1:mapState({自定义名称:'state中的数据名称'})
//mapState辅助函数方式
//在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.state_a,
// 传字符串参数 'state_a' 等同于 `state => state.state_a`
countAlias: 'state_a',
})
}
方式2:mapState(['state中的数据名称a','state中的数据名称b'])
//mapState辅助函数方式
//在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
computed: mapState(['state_a','state_b'])
}
对象展开运算符方式
方式1:...mapState({自定义名称:'state中的数据名称'})
//mapState辅助函数方式
//在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
computed: {
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({countAlias: 'state_a'})
}
}
方式2:...mapState(['state中的数据名称a','state中的数据名称b'])
//mapState辅助函数方式
//在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
computed:{
...mapState(['state_a','state_b'])
}
}
2. Getters
直接访问方式:this.$store.getters.getters变量
//直接访问方式
this.$store.getters.getters_a
mapGetters辅助函数方式 :
方式1:mapGetters({自定义名称:'getters中的数据名称'})
//mapGetters辅助函数方式
//在单独构建的版本中辅助函数为 Vuex.mapGetters
import { mapGetters } from 'vuex'
export default {
computed: mapGetters({
// 箭头函数可使代码更简练
count: getters => getters.getters_a,
// 传字符串参数 'getters_a' 等同于 `getters => getters.getters_a`
countAlias: 'getters_a',
})
}
方式2:mapGetters(['getters中的数据名称a','getters中的数据名称b'])
//mapGetters辅助函数方式
//在单独构建的版本中辅助函数为 Vuex.mapGetters
import { mapGetters } from 'vuex'
export default {
computed: mapGetters(['getters_a','getters_b'])
}
对象展开运算符方式
方式1:...mapGetters({自定义名称:'getters中的数据名称'})
//mapGetters辅助函数方式
//在单独构建的版本中辅助函数为 Vuex.mapGetters
import { mapGetters } from 'vuex'
export default {
computed: {
// 使用对象展开运算符将此对象混入到外部对象中
...mapGetters({countAlias: 'getters_a'})
}
}
方式2:...mapGetters(['getters中的数据名称a','getters中的数据名称b'])
//mapGetters辅助函数方式
//在单独构建的版本中辅助函数为 Vuex.mapGetters
import { mapGetters } from 'vuex'
export default {
computed:{
...mapGetters(['getters_a','getters_b'])
}
}
3. Mutations
直接提交方式:this.$store.commit(‘方法名称’,值)
//直接访问方式
this.$store.commit('mutations_a',false)
mapMutations 辅助函数方式
方式1:...mapMutations({自定义名称:'mapmutations中的方法名称'})
方式2:...mapMutations(['mapmutations中的方法名称a','mapmutations中的方法名称b'])
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'mutations_a', // 将 `this.mutations_a()` 映射为 `this.$store.commit('mutations_a')`
// `mapMutations` 也支持载荷:
'mutations_a' // 将 `this.mutations_a(false)` 映射为 `this.$store.commit('mutations_a', false)`
])
}
}
4. Actions
以载荷形式分发:this.$store.dispatch(‘方法名称’,值)
以载荷形式分发
this.$store.dispatch('actions_a',false)
以对象形式分发
// 以对象形式分发
store.dispatch({
type: 'Boolean',
state_a: false
})
在组件中分发 Action, mapActions 辅助函数方式
方式1:...mapActions({自定义名称:'mapActions中的方法名称'})
方式2:...mapActions(['mapActions中的方法名称a','mapActions中的方法名称b'])
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
import { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'actions_a', // 将 `this.actions_a()` 映射为 `this.$store.dispatch('actions_a')`
// `mapActions` 也支持载荷:
'actions_b' // 将 `this.actions_b(false)` 映射为 `this.$store.dispatch('actions_b', false)`
]),
...mapActions({
add: 'actions_b' // 将 `this.add()` 映射为 `this.$store.dispatch('actions_b')`
})
}
}
组合 Action
store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch 仍旧返回 Promise:
actions: {
actions_a ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
}
actions: {
// ...
actions_a({ dispatch, commit }) {
return dispatch('actions_a').then(() => {
commit('false')
})
}
}
// 假设 getData() 和 getOtherData() 返回的是 Promise
actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}
5. Modules
将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
五、Vue store 存储commit 和dispatch区别
主要区别是:
- dispatch:含有异步操作,例如向后台提交数据,写法:this.$store.dispatch(‘mutaions方法名’,值)
- commit:同步操作,写法:this.$store.commit(‘mutions方法名’,值)
脚下留心:官网参考网址