Vuex
Vuex
是一個專為Vue.js
應用程序開發的狀態管理模式。它采用集中式管理應用的所有組件狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。(類似于在前端的數據庫,這里的數據存儲在內存當中)
一、安裝并配置
在項目的終端中寫入如下的命令來安裝Vuex
:
npm install vuex --save
配置main.js
文件,導入Vuex
:
import Vuex from 'vuex'
Vue.use(Vuex);
- 它竟然可以存多個組件的狀態,當然要進行相應的一個配置,所以此時我們在項目的
src
目錄下創建一個新的目錄store
,并在內部準備一個配置文件index.js
import Vue from 'Vue'
import Vuex from 'Vuex'Vue.use(Vuex);// 公共state對象,存儲所有組件的狀態
const state = {user: {name:''}
}// 唯一取值的方法,計算屬性
const getters = {getUser(state) {return state.user;}
}// 唯一可以修改state值的方法,同步阻塞
const mutations = {updateUser(state, user) {state.user = user;}
}// 異步調用mutations方法
const actions = {asyncUpdateUser(user) {// context 是上下文的意思 針對的就是這個 js 文件// 且只能用 commit 進行調用mutations中的方法// 當調用actions中的方法也是只能dispatch進行調用context.commit('updateUser', user);}
}// 現在我們定義完了,此時就要將我們定義的內容暴露出去
export default new Vuex.Store({state,getters,mutations,actions
});
之后在main.js
中配置文件,再次引入我們剛剛寫好的store
目錄
import store from './store'
-
用戶信息的添加和獲取:
外界通過異步調用的方法,使用
dispatch()
調用添加,但是本質上還是使用的是mutations
中獲取信息的方法(唯一修改方法)
二、解決瀏覽器刷新后Vuex
數據消失問題
問題描述
? Vuex
的狀態存儲是響應式的,當Vue
組件從store
中讀取狀態的時候,若store
中的狀態發送變化,那么相應的組件也會得到高效的更新,但是有一個問題就是vuex
的存儲的數據只是在頁面中的,相當于我們定義的全局變量,刷新之后,里面的數據就會恢復到初始狀態。但是這種情況并不是我們所希望的
解決方案
? 監聽頁面是否刷新,如果頁面刷新了,將state
對象存入到sessionStorage
中。頁面打開之后,判斷sessionStorage
中是否存在state
對象,如果存在,則說明頁面是被刷新過的,將sessionStorage
中存的數據取出來給vuex
中的state
賦值,如果不存在,說明是第一次打開,則取vuex
中定義的state
初始值
代碼實現:
因為我們在任何一個組件中進行刷新,我們都需要判斷,但是我們不可能每一個組件中都設置判斷,所以我們干碎就直接定義為全局的組件,故需要在根組件
App.vue
中設置監聽刷新操作的事件
-
在
App.vue
中添加監聽刷新事件export default {name: 'App',mounted() {window.addEventListener('unload', this.saveState);},methods: {saveState() {window.sessionStorage.setItem('state', JSON.stringify(this.$store.state))}} }
-
修改
store/index.js
中的state
const state = null != window.sessionStorage.getItem('state') ? JSON.parse(window.sessionStorage.getItem('state')) : {user: {name: ''} }
三、模塊化
? 由于使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常復雜時,store
對象就可能變得相當臃腫。為了解決以上的問題,Vuex
允許我們將store
分割成模塊(module)
。每個模塊擁有自己的state
、mutation
、action
、getter
、甚至是嵌套子模塊一一從上至下進行同樣方式的分割
-
創建
user
模塊在
store
目錄下創建一個名為modules
的目錄并創建一個名為user.js
的文件,代碼如下:const user = {state : {user: {name:''} }// 唯一取值的方法,計算屬性 getters : {getUser(state) {return state.user;} }// 唯一可以修改state值的方法,同步阻塞mutations : {updateUser(state, user) {state.user = user;} }// 異步調用mutations方法actions : {asyncUpdateUser(user) {// context 是上下文的意思 針對的就是這個 js 文件// 且只能用 commit 進行調用mutations中的方法// 當調用actions中的方法也是只能dispatch進行調用context.commit('updateUser', user);}} }export default user;
注意:定義的
user.js
內部仍然是key : value
格式的,且最外層拿上const 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 : {user} });
由于組件中使用的是
getters
和actions
處理,所以調用代碼不變 -
修改
App.vue
export default {name: 'App',mounted() {window.addEventListener('unload', this.saveState);},methods: {saveState() {window.sessionStorage.setItem('userState', JSON.stringify(this.$store.state.user))}} }