淺談Vuex

什麼是Vuex?

     首先VuexVue '全家桶'的成員之一,也是一個專爲Vue.js應用程序開發的狀態管理模式。     官方說法: 它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。javascript

爲何要用Vuex?

    由於組件之間是相互獨立的,組件之間想要通訊。其中有經過props選項通訊,但這隻限於父子組件通訊,遠遠不能知足組件之間通訊的需求,特別是作中大型的項目。因此就把組件之間須要共享的數據給單獨'弄'出來。     經過定義和隔離狀態管理中的各類概念並經過強制規則維持視圖和狀態間的獨立性,咱們的代碼將會變得更結構化且易維護。vue

什麼狀況應該用Vuex?

    Vuex能夠幫助咱們管理共享狀態,並附帶了更多的概念和框架,這須要對短時間和長期效益進行權衡。     若是不是開發中大型單頁應用,使用Vuex多是繁瑣冗餘的,不建議使用。java

Vuex的特性

    每個 Vuex應用的核心就是 store(倉庫)。「store」基本上就是一個容器,它包含着你的應用中大部分的狀態 (state)。Vuex 和單純的全局對象有如下兩點不一樣:vuex

  1. Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地獲得高效更新。緩存

  2. 你不能直接改變 store 中的狀態。改變 store 中的狀態的惟一途徑就是顯式地提交 (commit) mutation。這樣使得咱們能夠方便地跟蹤每個狀態的變化,從而讓咱們可以實現一些工具幫助咱們更好地瞭解咱們的應用。框架

Vuex 的核心概念

     state:      把組件須要通訊的數據定義在storestate中。容器的狀態(響應式數據,能夠觸發視圖更新的數據)。 舉例:異步

//若是在模塊化構建系統中,請確保在開頭調用了 Vue.use(Vuex)
    //視圖狀態倉庫中(超大的ViewModel,把須要跨組件通訊的數據都放到這裏)
    const store = new Vuex.Store({
      //容器狀態(響應式數據,能夠觸發視圖更新的數據)
      state: {
        count: 0
      },)
//在組件中經過計算屬性來獲取 store.state中的成員
 Vue.component('component-b', {
    template: ` <div> componentB <h1>{{count }}</h1> </div> `,
    created () {
    },
    data () {
      return {
      }
    },
    computed: {  //使用computed 來監視count的變化,當count的值一變化,就會調用computed的事件
     count () {
      return store.state.count
     }
    }
  })
複製代碼

     getter:      就像計算屬性同樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被從新計算。 舉例:模塊化

const store = new Vuex.Store({
  state: {
   todos: [
    { name: '小張',compoleted: true},
    { name: '小李',compoleted: false }
   ]
  },
getters: {  
  compoletedTodos: state => {   //getter 接受state做爲其第一個參數
    return state.todos.filter (todo => toto.compoleted)
  },
comTodosLength: ( state, getters) => { //getter 也能夠接受其餘的getter做爲第二個參數
    return getters.compoletedTodos.length
}
}
})
經過屬性訪問
store.getters.compoletedTodos

複製代碼

     mutation:     它是更改Vuexstore中的狀態的惟一方法,很是相似於事件,每一個mutation 都有一個字符串的事件類型type和一個回調函數handle。 舉例:函數

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 變動狀態
      state.count++
    }
  }
})

在組件中經過store.commit方法來觸發mutation
store.commit('increment ')
複製代碼

經過store.commit傳入額外的參數,即mutation的載荷(payload): 舉例:工具

方式一:
mutations: {
  increment (state,n) {
     state.count += n
  }
}
store.commit('increment',10)
方式二: 載荷應該是一個對象
mutations: {
  increment (state,payload) {
   state.count += payload.amount
  }
}
store.commit('increment',{
  amount: 10
})
方式三:對象風格的提交方式,可是定義mutation函數保持不變
store.commit({
  type:'increment',
  amunt: 10
})
複製代碼

     action:      action 相似於 mutation,可是不一樣的是:

  • action 提交的是mutation,而不是直接變動狀態。
  • action能夠包含任何異步操做 舉例:
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
  //action 函數接受一個與store實例具備相同方法和屬性的context對象
    increment (context) {
      context.commit('increment')
    }
  }
})
複製代碼

action 經過 store.dispatch 觸發:

store.dispatch('increment')
複製代碼

actionmutation最大的不一樣是:mutation必須同步執行,而action就不受約束,能夠在action內部執行異步操做:

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}
複製代碼

action支持一樣的載荷方式和對象方式進行分發。      module:     當項目很是大的時候,應用的全部狀態會集中到一個比較大的對象,store對象就有可能變得至關臃腫。     爲了解決以上問題,咱們能夠將store分割成模塊,同時每一個模塊擁有本身的state,mutation,action,getter,還能嵌套子模塊,從上至下進行一樣方式的分割。

const moduleA = {
    state: { ... },
    mutations: { ... },
    actions: { ... },
    getters: { ... }
  }
 
 const moduleB = {
   state: { ... },
   mutations: { ... },
   actions: { ... }
 }

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的狀態
store.state.b // -> moduleB 的狀態
複製代碼

輔助函數

  • mapState輔助函數
  • mapGetters 輔助函數
  • mapMutations 輔助函數
  • mapActions 輔助函數

     其實關於Vuex還有不少知識點,尤大神已經寫的很全面了,你們感興趣的能夠參考Vuex(vuex.vuejs.org/zh/)的官網。

     我以爲學習最好的辦法就是跟着官網敲demo,這樣才能學以至用,更好的理解新的技術點。

     好了,不說了,我要去敲代碼了。若是我寫的對你有些幫助,不要忘了給我點個贊或加個關注喲。ღ( ´・ᴗ・` )比心

相關文章
相關標籤/搜索