簡介
Vuex 是一個專為 Vue.js 應用程式開發的 狀態管理模式,它采用集中式存盤管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化,
安裝
在專案根目錄執行如下命令來安裝 Vuex
若失敗,可使用cnpm
npm install vuex --save
修改 main.js 檔案,匯入 Vuex,關鍵代碼如下:
import Vuex from 'vuex'
Vue.use(Vuex);
判斷用戶是否登錄
我們利用路由鉤子 beforeEach 來判斷用戶是否登錄,期間會用到 sessionStorage 存盤功能
修改 Login.vue
在表單驗證成功方法內增加如下代碼:
設定用戶登錄成功
sessionStorage.setItem('isLogin', 'true');
修改 main.js
利用路由鉤子 beforeEach 方法判斷用戶是否成功登錄,關鍵代碼如下:
// 在跳轉前執行
router.beforeEach((to,from,next)=>{
// 獲取用戶登錄狀態
let isLogin = sessionStorage.getItem('isLogin')
// 注銷
if(to.path == '/logout'){
// 清空
sessionStorage.clear()
// 跳轉到登錄
next({path:'/login'})
}
// 如果請求的是登錄頁
else if(to.path == '/login'){
if(isLogin!=null){
// 跳轉到首頁
next({path:'/main'})
}
}
// 如果為非登錄狀態
else if(isLogin == null){
// 跳轉到登錄頁
next({path:'/login'})
}
// 下一個路由
next()
})
配置 vuex
創建 Vuex 組態檔
在 src 目錄下創建一個名為 store 的目錄并新建一個名為 index.js 檔案用來配置 Vuex,代碼如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 全域state物件,用于保存所有組件的公共資料
const state = {
// 定義一個user物件
// 在組件中是通過this.$store.state.user來獲取
user:{
username:''
}
}
// 實時監聽state值的最新狀態,注意這里的getters可以理解為計算屬性
const getters = {
// 組件中是通過this.$store.getters.getuser來獲取
getUser(state){
return state.user
}
}
// 定義改變state初始值的方法,這里是唯一可以改變state的地方,缺點是只能同步執行
const mutations = {
// 在組件中是通過this.$store.commit('updateUser',user);
// 方法來呼叫mutations
updateUser(state,user){
state.user = user
}
}
// 定義觸發mutations里函式的方法,可以異步執行mutations里的函式
const actions = {
// 在組件中是通過this.$store.dispatch('asyncUpdateUser',user)來呼叫actions
asyncUpdateUser(context,user){
context.commit('updateUser',user);
}
}
export default new Vuex.store({
state,
getters,
mutations,
actions
})
修改 main.js 增加剛才配置的 store/index.js ,關鍵代碼如下:
import Vue from 'vue'
import Vuex from 'vuex'
import store from './store'
Vue.use(Vuex)
new Vue({
el:'#app',
store
})
解決瀏覽器重繪后 Vuex 資料消失問題
問題描述
Vuex 的狀態存盤是回應式的,當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那么相應的組件也會相應地得到高效更新,但是有一個問題就是:vuex 的存盤的資料只是在頁面的中,相當于我們定義的全域變數,重繪之后,里邊的資料就會恢復到初始化狀態,但是這個情況有時候并不是我們所希望的,
解決方案
監聽頁面是否重繪,如果頁面重繪了,將 state 物件存入到 sessionStorage 中,頁面打開之后,判斷 sessionStorage中是否存在 state 物件,如果存在,則說明頁面是被重繪過的,將 sessionStorage 中存的資料取出來給 vuex 中的state 賦值,如果不存在,說明是第一次打開,則取 vuex 中定義的 state 初始值,
修改代碼
在 App.vue 中增加監聽重繪事件
export default {
name:'App',
mounted(){
window.addEventListener('unload',this.saveState)
},
methods:{
saveState(){
sessionStorage.setItem('state',JSON.stringify(this.$store.state))
}
}
}
修改 store/index.js 中的 state
const state = sessionStorage.getItem('state') ? JSON.parse(sessionStorage.getItem('state')): {
// 定義一個user物件
// 在組件中是通過this.$store.state.user來獲取
user:{
username:''
}
}
模塊化
由于使用單一狀態樹,應用的所有狀態會集中到一個比較大的物件,當應用變得非常復雜時,store 物件就有可能變得相當臃腫,為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module),每個模塊擁有自己的 state、 mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割
創建 user 模塊
在 store 目錄下創建一個名為 modules 的目錄并創建一個名為 user.js 的檔案,代碼如下:
const user = {
// 因為模塊化了,所以解決重繪問題的代碼需要改造一下
state:sessionStorage.getItem('userState')?JSON.parse(sessionStorage.getItem('userState')):{
user: {
username:''
}
},
getters:{
getUser(state){
return state.user
}
},
mutations:{
updateUser(state,user){
state.user = user
}
},
actions:{
asyncUpdateUser(context,user){
context.commit('updateUser',user)
}
}
}
修改 store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
export default new Vuex.Store({
modules:{
// this.$store.state.user
user
}
})
備注:由于組件中使用的是 getters 和 actions 處理,所以呼叫代碼不變
修改 App.vue
export default {
name:'App',
mounted(){
window.addEventListener('unload',this.saveState)
},
methods:{
saveState(){
// 模塊化后,呼叫state的代碼修改為this.$store.state.user
sessionStorage.setItem('userState',JSON.stringify(this.$store.state.user))
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/277712.html
標籤:其他
