Vue中的狀態管理器 - Vuex

咱們知道vue是組件式開發的,當你的項目愈來愈大後,每一個組件背後的數據也會變得愈來愈難以理順,html

這個時候你就能夠考慮使用vuex了。vue

備註: 官方建議小項目不要使用,引入vuex會帶來新的概念和模式,這對於新手而言理解上自己有難度,並且小項目中vuex發揮的功效確實不怎麼明顯,vuex

反而增長了開發難度,就像後端項目中常說的 過分設計。vue-cli

說了這麼多,下面介入正題(如下講解須要一個空的vue項目,推薦使用 vue-cli 建立,快速搭建一個vue開發環境 ):後端

vuex的做用就是做爲一個數據倉庫(store),把多個組件的背後的數據都放到store中,而後全部組件經過約定的方式去讀取數據和修改數據。網絡

這一句話就歸納完了。沒有想象的那麼複雜。注意,這句話裏面一個關鍵詞叫 約定,下面來講說有那些約定:app

在將約定以前,首先仍是要知道怎麼定義一個倉庫(store),進入項目而後  vue add vuex 。異步

經過這條命令,vue-cli 幫咱們建立了一個 store.js 的文件,並自動在根組件中引入了store,具體變化以下:ide

main.js 文件中自動變化了兩處函數

import Vue from 'vue'
import App from './App.vue'    
import store from './store' #【引入store文件】

Vue.config.productionTip = false

new Vue({
  store, #【在根組件中引入了store】
  render: h => h(App)
}).$mount('#app')

如今咱們編輯一下 store.js 文件:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
      user: {
        name: '張三', sex: '男'
      }
  },
  mutations: {
    change_name (state,payload) {
      state.user.name = payload.new_name
    },
    change_sex (state,payload) {
      state.user.sex = payload.new_sex
    }
  },
  actions: {
    change_sex_by_action (context,payload) {
      setTimeout(() => {
        context.commit('change_sex',payload)
      },3000)
    }
  }
})

理解:

  state 是狀態(數據中心)。

  mutations 裏面定義的函數用來修改state,mutation只能執行同步操做。

  actions 的目的也是更改state,可是他不像mutation同樣能夠直接更改state,而是經過調用mutation來更改state。還有一個不一樣點是,action能夠執行異步操做,好比網絡請求。

  getters 返回組裝DIY後的數據,好比state有個sex=「女」,經過getter在後面加一個 生 ,返回 女生,可是我以爲把組件中 computed 乾的事情放到store層不是一個好主意,因此本例中不涉及。

用法:

  mutation的一個參數是 state,第二個參數是從 組件傳過來的參數對象,

  action的第一個參數是一個與 store 實例具備相同方法和屬性的 context 對象,這句話有點難以理解,你就把context想象成一個新的store對象,

  第二個參數仍是 組件傳過來的參數對象

在編輯一下 App.vue 文件

<template>
  <div id="app">
    <button @click="change_name">change name by mutation</button>
    <p>current name({{ user.name }})</p>
    <button @click="change_sex">change sex by action</button>
    <p>current sex({{ user.sex }})</p>
  </div>
</template>
<script>
export default {
  data () {
    return {
      // user: this.$store.state.user
    }
  },
  computed: {
    user() {
      return this.$store.state.user
    }
  },
  methods: {
    change_name() {
      this.$store.commit({
        type: 'change_name',
        new_name: '李四'
      })
    },
    change_sex() {
      this.$store.dispatch({
        type: 'change_sex_by_action',
        new_sex: '女'
      })
    }
  }
}
</script>

 經過store獲取數據都要放到computed裏面,雖然在其餘地方也能夠直接獲取,可是沒法監聽數據變更(就像上面註釋的同樣)。

change_name是經過mutation方式同步更改store中的數據,change_sex採用了action方式異步更改store中的數據。

若是在computed中須要獲取的數據不少,可使用 官方提供的 mapState,具體用法查看官方 文檔 。

我本身的理解:

不要濫用store,不要把全部的數據都放到store中,在組件化開發思想下,我認爲組件和組件之間本就應該獨立封裝,

若是一個數據只有在某個組件中使用,而不須要被其餘組件共享,那麼最好不要放到其中,store只存儲有必要的數據,不要讓他變得太臃腫,不然麻煩早晚會來。

官方文檔中說明,若是store太大能夠採用模塊方式分割,但貌似不太優雅,

最後我仍是推薦store只放必要的東西,不要讓他變得太肥胖。

相關文章
相關標籤/搜索