一、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) })