Vuex是一個狀态管理的插件,管理過程包含了state(資料源)、view(state綁定到視圖)、actions(view改變同步改變資料源)三個狀态,頁面重新整理的時候vuex裡的資料會重新初始化,導緻資料丢失,頁面會重新加載vue執行個體,vuex裡面的資料就會被重新指派,解決辦法:将vuex中的資料直接儲存到浏覽器緩存中(sessionStorage、localStorage、cookie),界面重新整理前把資料存sessionStorage或再次請求遠端資料,使之動态更新vuex資料,App.vue中添加以下代碼
// App.vue
//===========================下面是解決重新整理頁面丢失vuex資料
created() {
//在頁面加載時讀取sessionStorage裡的狀态資訊
if (sessionStorage.getItem('store')) {
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store'))));
}
//在頁面重新整理時将vuex裡的資訊儲存到sessionStorage裡
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('store', JSON.stringify(this.$store.state));
});
}
應用場景:(購物車的資料共享,登入注冊)
- 多個視圖依賴于同一狀态
- 來自不同視圖的行為需要變更同一狀态
- 可以思考到涉及
、sessionStorage
之類的裡面或涉及到非父子關系的元件,例如兄弟關系、祖孫關系,甚至更遠的關系元件之間的聯系cookies
Vuex使用:
- 安裝:cnpm install vuex --save
- 引入:import Vuex from 'vuex' Vue.use(Vuex)
- 建立: new Vuex.Store({})
- 使用:挂載到new Vue()上,new Vue({store })
new Vuex.Store 配置
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
},
mutations: {
todosAdd(state,obj) {
// 變更狀态
state.todos.push(obj)
}
},
actions: {
todosAddM(context,obj){ // context屬性:state、rootState、commit、dispatch、getters、rootGetters
context.commit('todosAdd',obj)
}
},
modules: {
a: moduleA, // moduleA配置和根子產品的選項一樣,store.state.a // -> moduleA 的狀态
b: moduleB
}
})
export default store;
- store、modules:存儲資料
- getters:計算屬性,可以了解為跟computed一樣,通路 store.getters.doneTodos
- mutations:通過裡面方法改變state裡面的資料,通過 store.commit('todosAdd',{id: 3,text:'''}) 調用,同步處理
- actions:不能直接修改state,通過觸發mutations來修改,可操作異步、多個同步處理,通過 store.dispatch('todosAddM',{id: 3,text:'''})調用
Store讀取
- 可以直接
時從中讀取created
值,通過$store.state
來修改值commit()
- mapState、mapGetters、mapActions、mapMutations:當一個元件需要擷取多個狀态時使用,import { mapState } from 'vuex'
<template> <div id="example"> {{count}} </div> </template> <script> import { mapState } from 'vuex' export default { data () { return { str: '國籍', dataCount: this.$store.state.count } }, computed: mapState({ count: 'count', // 第一種寫法 from: function (state) { // 用普通函數this指向vue執行個體,要注意 return this.str + ':' + state.from } }), methods: { increment () { this.$store.commit('increment') }, decrement () { this.$store.commit('decrement') } }, created () { // 寫個定時器,發現computed依舊保持了隻要内部有相關屬性發生改變不管是目前執行個體data中的改變,還是vuex中的值改變都會觸發dom和值更新 setTimeout(() => { this.str = '國家' }, 1000) } } </script>