Vuex小結
前言
? 近期的專案中多次用到了Vuex,感覺對Vuex不太熟悉,趁著周末學習了一波,現在來總結一下,
1、Vuex是什么
官網Vuex 是什么? | Vuex (vuejs.org)的描述
Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式,它采用集中式存盤管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化,
個人理解vuex就是一個用來共享資料的,在Vuex里存的資料所有的組件都可以訪問到,而不必進行復雜的組件通訊,
vuex的核心就是state,getters,mutations,actions,modules這5個核心概念,
- state,Vuex中共享的資料
- getters,可以理解為Vuex中的計算屬性
- mutations,用來修改state的,更改 Vuex 的 state中的狀態的唯一方法是提交 mutation,只能是同步的操作
- actions,類似于mutation,可以進行異步的操作
- modules,Vuex中資料模塊化
2、vuex如何使用
安裝
# yarn
$ yarn add vuex
# or npm
$ npm i vuex
在store/index.js中代碼
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './module/a'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
msg: 'goodnight everyone!!'
},
mutations: {
},
actions: {
},
getters: {
},
modules: {
moduleA,
}
})
在main.js中
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
// 給Vue實體注入store,在組件中可以通過this.$store訪問到Vuex的資料
store,
render: h => h(App)
}).$mount('#app')
最后在任意組件中,都可以通過this.$store來訪問Vuex中的store
如:在App.vue中
<template>
<div id="app">
{{ $store.state.msg }}
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
當我們想要修改state中的資料時,需要提交mutation來修改
mutations: {
SET_MSG: (state, value) => {
state.msg = value
}
},
// 在vue檔案中
this.$store.commit('SET_MSG', 'xxxxx')
如果需要進行一些異步的操作,則mutation就不行了,需要在action中來提交mutation
actions: {
setMsg: ({commit}, value) => {
commit('SET_MSG', value)
// 還可以回傳commit的結果,這是一個promise物件
return commit('SET_MSG', value) // Promise
}
}
// 在vue檔案中
this.$store.dispatch('setMsg', 'xxxxx')
// 如果action中return了mutation的commit,那么就可以進行.then 或者await操作
this.$store.dispatch('setMsg', 'xxxxx').then(() => {
// ...
})
// 或者在一個async 修飾的異步函式中使用await
await this.$store.dispatch('setMsg', 'xxxxx')
3、Vuex中的輔助函式
mapState
當一個組件需要獲取多個狀態的時候,將這些狀態都宣告為計算屬性會有些重復和冗余,為了解決這個問題,我們可以使用 mapState 輔助函式幫助我們生成計算屬性
// 在單獨構建的版本中輔助函式為 Vuex.mapState
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭頭函式可使代碼更簡練
count: state => state.count,
// 傳字串引數 'count' 等同于 `state => state.count`
countAlias: 'count',
// 為了能夠使用 `this` 獲取區域狀態,必須使用常規函式
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
當映射的計算屬性的名稱與 state 的子節點名稱相同時,我們也可以給 mapState 傳一個字串陣列
computed: mapState([
// 映射 this.count 為 store.state.count
'count'
])
利用展開運算子與區域計算屬性混合使用
computed: {
localComputed () { /* ... */ },
// 使用物件展開運算子將此物件混入到外部物件中
...mapState({
// ...
})
}
mapGetters
和mapState使用方法一樣
mapMutations和mapActions
和mapState用法類似,只不過是將mutations或actions映射成methods
methods: {
...mapActions([
// 映射 this.setMsg('xxx') 為 store.$dispatch('setMsg', 'xxx')
'setMsg'
]),
...mapMutations([
// 映射this.SET_MSG('xxx') 為store.commit('SET_MSG', 'xxx')
'SET_MSG'
])
}
4、Vuex頁面重繪后資料丟失
原因:
store里的資料是保存在運行記憶體中的,當頁面重繪時,頁面會重新加載vue實體,store里面的資料就會被重新賦值初始化
解決方法一:
利用sessionStorage或localStorage或者或cookie進行快取,beforeunload事件可以在頁面重繪前觸發,監聽beforeunload事件,在app.vue的生命周期中進行store中資料的存盤和初始化,這里以存在sessionStorage中為例
export default {
name: 'App',
created () {
// 在頁面加載時讀取sessionStorage里的狀態資訊
if (sessionStorage.getItem('vuex')) {
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('vuex'))))
}
// 在頁面重繪時將vuex里的資訊保存到sessionStorage里
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('vuex', JSON.stringify(this.$store.state))
})
}
}
解決方法二:
利用第三方庫,vuex-persistedstate進行Vuex資料的持久化,
安裝
$ yarn add vuex-persistedstate
在vuex初始化時候,作為組件引入,
import persistedState from 'vuex-persistedstate'
export default new Vuex.Store({
// ...
plugins: [persistedState()]
})
默認是持久化所有的state,也可以自行配置
可以參考這兩個鏈接:vuex持久化 vuex-persistedstate - 簡書 (jianshu.com)
robinvdvleuten/vuex-persistedstate: ?? Persist and rehydrate your Vuex state between page reloads. (github.com)
5、v-model如何與Vuex中的資料進行雙向系結
假設store/index.js中代碼如下
import Vue from 'vue'
import Vuex from 'vuex'
import persistedState from 'vuex-persistedstate'
export default new Vuex.Store({
state: {
msg: 'hello vuex',
userInfo: {
username: '',
password: ''
}
},
mutations: {
SET_MSG: (state, value) => {
state.msg = value
},
SET_USER_INFO(state, value) => {
state.userInfo = value
}
},
actions: {
setUserInfo: ({commit}, value) {
commit("SET_USER_INFO", value)
}
}
plugins: [persistedState()]
})
<script>
import { mapState, mapActions, mapMutations } from 'vuex'
export default {
computed: {
...mapState(['userInfo']),
// 和簡單資料型別進行系結,需要提供setter,在setter中(分發actions)提交mutation修改state
msg: {
get() {
return this.$store.state.msg
}
set(value) {
this.SET_MSG(value)
}
}
},
// 和復雜資料型別進行系結,需要深度監聽,在handler中(分發actions—)提交mutation修改state
watch: {
userInfo: {
handler(userInfo) {
this.setUserInfo(userInfo)
},
deep: true
}
},
methods: {
...mapActions(['setUserInfo']),
...mapMutations['SET_MSG']
}
</script>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/228856.html
標籤:JavaScript
