Vuex小結

Vuex小結

前言

​ 近期的項目中屢次用到了Vuex,感受對Vuex不太熟悉,趁着週末學習了一波,如今來總結一下。javascript

一、Vuex是什麼

官網Vuex 是什麼? | Vuex (vuejs.org)的描述vue

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。java

我的理解vuex就是一個用來共享數據的,在Vuex裏存的數據全部的組件均可以訪問到,而沒必要進行復雜的組件通信。git

vuex的核心就是state,getters,mutations,actions,modules這5個核心概念。github

  • state,Vuex中共享的數據
  • getters,能夠理解爲Vuex中的計算屬性
  • mutations,用來修改state的,更改 Vuex 的 state中的狀態的惟一方法是提交 mutation,只能是同步的操做
  • actions,相似於mutation,能夠進行異步的操做
  • modules,Vuex中數據模塊化

二、vuex如何使用

安裝vuex

# yarn
$ yarn add vuex
# or npm
$ npm i vuex

在store/index.js中代碼shell

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中npm

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中promise

<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')

三、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'
    ])
}

四、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)

五、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>
相關文章
相關標籤/搜索