官方文档地址:https://vuex.vuejs.org/zh/
官方文档已经很完善,推荐不熟悉vuex的同学可以多多阅读官方文档
vuex是vue的一个全局状态管理工具,一般作为vue的全局数据存储中心
1.常规使用
store.js中
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
getters: {
getCountString(state) {
return state.count + ''
}
},
mutations: {
setCount (state, data) {
state.count = data
}
},
actions: {
setCountAsync(store, data) {
setTimeout(()=>{
store.commit('setCount', data)
}, 500)
}
}
})
export default store
如上所示,作为数据管理器,store存在set与get方法
其中
set方法即为store配置项中的mutations与actions
get方法为getters与state
任意vue页面中使用
<template>
<div id="app">
{{ count }}
</div>
</template>
<script>
import { mapState,mapGetters,mapActions, mapMutations } from 'vuex'
export default {
name: "app",
computed: {
...mapState(['count']),
...mapGetters(['getCountString'])
},
methods: {
...mapMutations(['setCount']),
...mapActions(['setCountAsync']),
}
};
</script>
在以上代码中,可以在当前页面的实例中
通过this.count获取vuex中的count
通过this.getCountString获取count的字符串形式
通过this.setCount(n)将count设置为n
通过this.setCountAsync(n)将count异步设置为n
mapState,mapGetters,mapActions, mapMutations为vuex提供的辅助函数,可以将vuex中对应键名的数据或函数挂载到当前实例,通过this访问
当键名发生冲突时也可以另外映射
...mapMutations({
changeCount: 'setCount'
})
该句意为将this.$store.commit(‘setCount’, n )映射为this.changeCount(n)
actions相同
通常不建议重命名,会导致代码追溯困难
不使用辅助函数时,也可以这样使用
this.$store.state.count
this.$store.getters.getCountString
this.$store.commit('setCount', n )
this.$store.dispatch('setCountAsync', n)
在独立js中,可将store.js引入
用store代替this.$store即可
在vue中推荐使用辅助函数,在一个页面需要多处用到store数据时方便管理
2.项目中使用
持久化
在项目中,由于store会在刷新后重置,我们需要考虑持久化的场景,这时候可以考虑通过
vuex-persist
进行数据的持久化
yarn add vuex-persist
or
npm install vuex-persist
使用时,需考虑对低版本浏览器的兼容,即配置babel编译目录包括该目录,具体配置如下
高版本cli, vue.config.js中
// in your vue.config.js
module.exports = {
/* ... other config ... */
transpileDependencies: ['vuex-persist']
}
低版本cli, build/webpack.config.js中
module.exports = {
/* ... other config ... */
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('vuex-persist')]
}]
}
}
需注意,持久化方案一般为将数据json化后存储到sessionStorage或localStorage
故此方案只支持可以json化的数据类型的持久化,当store中存在复杂数据类型,如socket等对象时
需考虑初始化方案
模块化
在稍大的项目中,当vuex中存放的数据达到几十甚至上百条时,这时使用单一的state已经很难去管理了,维护起来也很困难,这种情况就需要进行模块化了
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import VuexPersist from "vuex-persist";
import user from './user'
Vue.use(Vuex);
const VuexLocal = new VuexPersist({
modules: ['user'],
storage: sessionStorage
});
export default new Vuex.Store({
modules: {
user
},
plugins: [VuexLocal.plugin]
})
user.js
import { ayList } from "@/api/judge"
import { treeToList } from "@/utils/tool"
export default {
namespaced: true,
state: {
token: '',
userInfo: {},
menuTree: [],
menuList: [],
ayList: [],
},
mutations: {
updateToken(state, data = '') {
state.token = data
},
updateUserInfo(state, data = {}) {
state.userInfo = data
},
updateMenuTree(state, data = []) {
state.menuTree = data
state.menuList = treeToList(data)
},
updateAyList(state, data = []) {
state.ayList = data
},
clearUser(state) {
// 保持数据类型一致
for (const key in state) {
if (typeof state[key] == "object") {
if (Array.isArray(state[key])) {
state[key] = []
} else {
state[key] = {}
}
} else {
state[key] = ""
}
}
}
},
actions: {
setAyList(store) {
let userId = store.state.userInfo.userId
ayList({
userId
}).then(res => {
const ayList = res.data.map(i => ({ value: i, label: i }))
store.commit('updateAyList', ayList)
})
},
}
}
其中,ayList返回值为Promise对象,为异步方法
注意,模块化的情况下,需将模块化的namespaced值为true, 方便管理追踪
在vue中使用
<template>
<div id="app">
{{ userInfo.name }}
</div>
</template>
<script>
import { createNamespacedHelpers } from "vuex";
const { mapState: mapUserState, mapMutations: mapUserMutations, mapActions: mapUserActions } = createNamespacedHelpers("user");
export default {
name: "app",
computed: {
...mapUserState(['userInfo','ayList']),
},
created() {
this.init()
this.read()
},
methods: {
...mapUserMutations(['updateUserInfo']),
...mapUserActions(['setAyList']),
init() {
this.setAyList()
this.updateUserInfo({userName: 'ssc',userId: 1})
console.log(this.userInfo)
console.log(this.ayList)
},
read() {
this.$store.dispatch('user/setAyList')
this.$store.commit('user/updateUserInfo', {userName: 'ssc',userId: 1})
console.log(this.userInfo)
console.log(this.ayList)
},
reset() {
this.$store.commit('user/clearUser')
}
},
};
</script>
以上为vuex的基本用法,更多用法可查看官网