一、vuex是什么
vuex 是一个专门为vue.js应用程序开发的状态管理模式。
这个状态我们可以理解为在data中的属性,需要共享给其他组件使用的部分。可以理解为vue的全局变量,使用vuex进行统一集中式的管理。
项目中引用vuex
npm install vuex --save
二、vuex的五种基本的对象:
- state:存储状态(变量)
- getters:对数据获取之前的再次编译,可以理解为state的计算属性。我们在组件中使用 $sotre.getters.fun()
- mutations:修改状态,并且是同步的。在组件中使用$store.commit('',params)。这个和我们组件中的自定义事件类似。
- actions:异步操作。在组件中使用是$store.dispath('')
- modules:store的子模块,为了开发大型项目,方便状态管理而使用的。这里我们就不解释了,用起来和上面的一样。
下面我们从实际代码看下这五个基本对象的使用,下图为实际项目的目录结构。
项目安装好vuex后我们开始使用(安装代码第一节提到),我们引用vuex
上面代码中app,user,initdData,pageInfo为store子模块;在初始化store的时候将store子模块包含,代码如下:
const store = new Vuex.Store({
// 子模块引入
modules: {
app, user, initData, pageInfo
},
getters
})
export default store
然后进入子模块看下子模块结构,我们以user子模块为例,通过简单的代码演示下代码结构。
// import { getToken, setToken, removeToken } from '@/utils/tools/auth'
const user = {
state: {
token: '',
username: '',
userid: '',
count: 0
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_USERNAME: (state, name) => {
state.username = name
},
SET_ID: (state, userId) => {
state.userId = userId
},
AddCount(state, n = 0) {
return (state.count += n)
},
ReduceCount(state, n = 0) {
return (state.count -= n)
}
},
actions: {
// 登录
Login({ commit }, userInfo) {
const username = userInfo.username.trim()
return new Promise((resolve, reject) => {
global.api.getLogin({ username: username, pwd: userInfo.pwd, code: userInfo.code }).then(response => {
const data = response.data
commit('SET_TOKEN', data.token)
commit('SET_USERNAME', data.username)
commit('SET_ID', data.id)
localStorage.setItem('TOKEN', data.token)
resolve(response)
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
global.api.getLoginInfo().then(response => {
const data = response.data
commit('SET_TOKEN', data.token)
commit('SET_USERNAME', data.username)
commit('SET_ID', data.id)
resolve(response)
}).catch(error => {
console.log('error')
reject(error)
})
})
},
// 登出
LogOut({ commit, state }) {
return new Promise((resolve, reject) => {
global.api.getLogout().then(response => {
commit('SET_TOKEN', '')
commit('SET_USERNAME', '')
commit('SET_ID', '')
localStorage.clear()// 清空缓存数据
sessionStorage.clear()// 清空缓存数据
resolve()
}).catch(error => {
console.log('err', error)
reject(error)
})
})
},
actionsAddCount(context, n = 0) {
console.log(context)
return context.commit('mutationsAddCount', n)
},
actionsReduceCount({ commit }, n = 0) {
return commit('mutationsReduceCount', n)
}
}
}
export default user
通过上面代码不难看出,我们使用state存储变量,通过mutations里面的方法来修改state中的变量值。actions是各个组件调用的方法,actions方法中可以调用数据接口查询数据库数据,然后通过使用mutations中的方法来修改state中的变量。
到这里我们已经能够在组件使用state或者mutations了。
//组件中使用state <template> <div class="hello"> <h3>{{$store.user.id}}</h3> </div> </template>
组件中使用mutations
<template> <div class="hello"> <h3>{{$store.user.count}}</h3> <div> <button @click="handleAddClick(10)">增加</button> <button @click="handleReduceClick(10)">减少</button> </div> </div> </template> methods: { handleAddClick(n){ this.$store.commit('AddCount',n); }, handleReduceClick(n){ this.$store.commit('ReduceCount',n); } }
组件中使用actions,使用dispath来触发actions中的方法
<div>异步操作</div> <div> <button @click="handleActionsAdd(10)">异步增加</button> <button @click="handleActionsReduce(10)">异步减少</button> </div> handleActionsAdd(n){ this.$store.dispatch('actionsAddCount',n) }, handleActionsReduce(n){ this.$store.dispatch('actionsReduceCount',n) }
接下来我们在看下getters,一般使用getters来获取我们的state,因为它算是state的一个计算属性,代码如下
const getters = { token: state => state.user.token, name: state => state.user.username, userId: state => state.user.id, getterCount: state => { state.count += 10 } } export default getters
通过getters使用state属性
<h3>{{$store.getters.getterCount}}</h3>
到这里如果你都能看懂,使用vuex也就没啥太大压力了。
三、mapState, mapMutations, mapActions, mapGetters使用
vuex官方给了我们一个更简单的使用vuex的方式,也就是 {mapState, mapMutations, mapActions, mapGetters}
<script> import {mapState, mapMutations, mapActions, mapGetters} from 'vuex' export default { name: 'HelloWorld', data () { return { msg: 'Welcome to Your Vue.js App' } }, methods: { ...mapMutations({ handleAddClick: 'mutationsAddCount', handleReduceClick: 'mutationsReduceCount' }), ...mapActions({ handleActionsAdd: 'actionsAddCount', handleActionsReduce: 'actionsReduceCount' }) // handleAddClick(n){ // this.$store.commit('mutationsAddCount',n); // }, // handleReduceClick(n){ // this.$store.commit('mutationsReduceCount',n); // }, // handleActionsAdd(n){ // this.$store.dispatch('actionsAddCount',n) // }, // handleActionsReduce(n){ // this.$store.dispatch('actionsReduceCount',n) // } }, computed: { count(){ return this.$store.getters.getterCount } } } </script>
最后一步就是在main.js中注册vuex,引入store,引入后我们就可以在各个组件中使用定义的全局变量了。
import Vue from 'vue' import App from './App' import store from './store' // 全局变量 import router from './router' // 路由 import plugins from './components' // 组件 import '@/icons' // icon // svg组件 import '@/permission' // permission control import moment from 'moment' import myUtils from './utils' // 帮助文件 import VueRouter from 'vue-router' // 引用路由组件 Vue.use(ElementUI, { zhLocale }) // 使用element-ui Vue.use(plugins) // 引用组件 Vue.use(VueRouter) Vue.prototype.api = myUtils.api.Api global.api = myUtils.api.Api global.Notification = ElementUI.Notification Vue.prototype.upload = myUtils.api.Upload Vue.prototype.$moment = moment Vue.config.productionTip = false Vue.prototype.printData = myUtils.api.printData new Vue({ el: '#app', router, store, render: h => h(App) })