此篇文章是介紹利用 vuex 儲存用戶登錄時的相關(guān)信息的使用方法。
聲明:前面部分是剛開始對vuex的接觸,后面部分是學(xué)習(xí)后對vuex使用的部分優(yōu)化,想直接用最新的,可以直接找到 20200819 部分。
效果圖:

使用方法:
相關(guān)配置文件

index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
export default new Vuex.Store({
//模塊引入
modules:{
user:user
}
})
user.js
export const USER_SIGNIN = 'USER_SIGNIN' //登錄成功
export const USER_SIGNOUT = 'USER_SIGNOUT' //退出登錄
export const USER_INFO_COMMIT = 'USER_INFO_COMMIT' //配合sessionStorage解決vux刷新丟失問題
export default {
// 存儲狀態(tài)(變量)
state: {
userInfo: {},//儲存用戶相關(guān)信息
userLogin: false,//用戶登錄狀態(tài)
},
// 對數(shù)據(jù)獲取之前的再次編譯,可以理解為state的計算屬性 this.$store.getters.方法名。
getters: {
},
// 修改狀態(tài),并且是同步的。在組件中使用$store.commit('',params)
mutations: {
//用戶登陸方法
[USER_SIGNIN](state, user) {
//儲存用戶相關(guān)信息
sessionStorage.setItem('userInfo', JSON.stringify(user))
sessionStorage.setItem('userLogin', 'true')
if (JSON.stringify(user)) {
//解決用戶信息未及時更新問題
Object.assign(state.userInfo, sessionStorage.getItem('userInfo') ? JSON.parse(sessionStorage.getItem('userInfo')) : user)
//更新用戶登錄狀態(tài)
state.userLogin = sessionStorage.getItem('userLogin') ? JSON.parse(sessionStorage.getItem('userLogin')) : false
}
},
//用戶退出登錄方法
[USER_SIGNOUT](state) {
state.userLogin = false;
state.userInfo = {};
//清除sessionStorage內(nèi)的所有記錄
sessionStorage.clear();
},
//解決瀏覽器刷新頁面數(shù)據(jù)丟失問題(根據(jù)之前儲存的sessionStorage相關(guān)信息來判斷)
[USER_INFO_COMMIT](state) {
Object.assign(state.userInfo, sessionStorage.getItem('userInfo') ? JSON.parse(sessionStorage.getItem('userInfo')) : {})
state.userLogin = sessionStorage.getItem('userLogin') ? JSON.parse(sessionStorage.getItem('userLogin')) : false;
},
},
// 異步操作
actions: {
[USER_SIGNIN]({ commit }, user) {
commit(USER_SIGNIN, user)
},
[USER_SIGNOUT]({ commit }) {
commit(USER_SIGNOUT)
},
[USER_INFO_COMMIT]({ commit }) {
commit(USER_INFO_COMMIT)
}
}
}
main.js
import store from './store/index' //引入
/* eslint-disable no-new */
new Vue({
el: '#app',
store, //引入
router,
components: { App },
template: '<App/>'
})
配置完成后,就可以直接在vue組件中使用
xxx.vue組件
<template>
<div style="margin:200px 0">
<p>登錄狀態(tài):{{userLogin}}</p>
<p>用戶信息:{{userInfo}}</p>
<button @click="loginIn()">登錄</button>
<button @click="loginOut()">退出</button>
</div>
</template>
<script>
export default {
computed: {
userLogin() {
if (this.$store.state.user.userLogin) {
return this.$store.state.user.userLogin;
} else {
this.$store.commit("USER_INFO_COMMIT");
return this.$store.state.user.userLogin;
}
},
userInfo() {
if (this.$store.state.user.userLogin) {
return this.$store.state.user.userInfo;
} else {
this.$store.commit("USER_INFO_COMMIT");
return this.$store.state.user.userInfo;
}
}
},
data() {
return {
userMsg: {
name: "小明",
age: "18",
sex: "男"
}
};
},
methods: {
loginIn() {
this.$store.commit("USER_SIGNIN", this.userMsg);
},
loginOut() {
this.$store.commit("USER_SIGNOUT");
}
}
};
</script>
<style>
</style>
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
20200819代碼優(yōu)化調(diào)整:
程序員都是在不斷成長的,下面的代碼是針對之前使用vuex的部分優(yōu)化。

模塊引入:
相比之前的模塊引入,這邊也是同樣按照 modules 目錄下,進(jìn)行的配置。不過是直接通過遍歷文件目錄實現(xiàn)的,不需要再一個個去寫了。
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
Vue.use(Vuex)
// 把modules文件下的 js文件返回出來
// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)
// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
// set './app.js' => 'app'
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
const store = new Vuex.Store({
modules,
getters
})
export default store
getters.js
getters.js里面是所有你想對外報漏的數(shù)據(jù)
const getters = {
name: state => state.user.name,
phoneNo: state => state.user.phoneNo,
}
export default getters
user.js
login, logout, getInfo 相當(dāng)于針對用戶的一些api接口;(可以忽視掉)
state 里面儲存的為用戶token,name和phoneNo,其中在getters.js里面,可以實現(xiàn)了針對 user 模塊內(nèi) name和phoneNo 數(shù)值的對外暴露
mutations 里面實現(xiàn)了重置用戶信息,儲存用戶token,儲存name,儲存phoneNo的修改方法;
actions 里面是針對用戶登錄,獲取用戶信息,以及用戶退出登陸的異步方法。此處你會看到有使用 Promise 異步操作,主要用于使用過程中的 await數(shù)據(jù)等待處理。 不太理解async/await 的可 參考此篇文章。
namespaced: true,主要是為了解決不同模塊命名沖突的問題,將不同模塊的namespaced:true,之后在不同頁面中引入getter、actions、mutations時,需要加上所屬的模塊名。
類似這樣,就可以在使用頁面內(nèi),直接對vuex內(nèi),user模塊內(nèi)的login用戶登陸方法進(jìn)行調(diào)用。
this.$store.dispatch("user/login");
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
const getDefaultState = () => {
return {
token: getToken(),
name: "",
phoneNo: "",
}
}
const state = getDefaultState()
const mutations = {
RESET_STATE: (state) => {
Object.assign(state, getDefaultState())
},
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
},
SET_PHONENO: (state, phoneNo) => {
state.phoneNo = phoneNo
},
}
const actions = {
// 用戶登錄,獲取token,并儲存到cookie里面
login({ commit }, userInfo) {
return new Promise((resolve, reject) => {
commit('SET_PHONENO', '15518270529')
resolve()
// //調(diào)用登錄接口
// login().then(response => {
// const { data } = response
// // 儲存到cookie里面
// commit('SET_TOKEN', data.token)
// setToken(data.token)
// resolve()
// }).catch(error => {
// reject(error)
// })
})
},
//調(diào)用獲取用戶信息的接口
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
//調(diào)用獲取用戶信息接口
getInfo().then(response => {
const { data } = response
if (!data) {
reject('Verification failed, please Login again.')
}
const { name, phoneNo } = data
commit('SET_PHONENO', phoneNo)
commit('SET_NAME', name)
resolve(data)
}).catch(error => {
reject(error)
})
})
},
//用戶退出登錄
logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
removeToken() // must remove token first
commit('RESET_STATE')
resolve()
}).catch(error => {
reject(error)
})
})
},
}
export default {
namespaced: true,
state,
mutations,
actions
}
xxx.vue組件
import { mapGetters } from "vuex";
//計算屬性
computed:{
//通過getter.js對外暴露的 phoneNo 值進(jìn)行使用
// {{phoneNo}} 數(shù)值使用
...mapGetters(['phoneNo'])
},
methods: {
async isLogin() {
//使用 try/catch 抓取錯誤信息,如果登陸失敗則會輸出錯誤信息,不往下執(zhí)行
try {
await this.$store.dispatch("user/login");
//如果登陸成功才會 輸出 ‘登陸成功’
console.log('登陸成功')
} catch (error) {
console.log(error);
}
}
}