vuex總結

Vuex是經過建立一個store的實例並配置相應的配置項來管理公共狀態的javascript

1、State:vuex中的‘data’vue

組 件中引入vuex中的store實例後經過store.state.屬性來訪問vuex中統一管理的數據,組件中從vuex中讀取狀態最簡單的方法是在計算屬性中,這樣vuex中的狀態變化的時候計算屬性就會從新求取計算屬性,並更新domjava

使用store中的state問題一:每一個組件使用的時候都須要引入store,vuex

解決:經過根實例中註冊store選項,該store實例就會注入到根組件下的全部子組件,子組件中經過this.$store訪問數組

問題二:當一個組件須要多個狀態時須要定義多個計算屬性,很繁瑣,promise

解決:可使用輔助函數mapState來統一導入dom

// 在單獨構建的版本中輔助函數爲 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'

])

  

問題三:上述能總體引入屬性了,可是沒有辦法將它與局部計算屬性混合使用異步

解決:使用對象展開運算符,將上邊的mapState前邊加上…,在寫其餘的計算屬性就能夠混合使用了函數

computed: {

  localComputed () { /* ... */ },

  // 使用對象展開運算符將此對象混入到外部對象中

  ...mapState({

    // ...

  })

}

注意:雖然vuex方便管理狀態,可是沒有必要將全部的都放入vuex中,那樣會形成代碼冗長不直觀,能夠把須要公用的狀態放入vuex中this

 

2、Getter:vuex中的‘computed’

經過store中的state派生一些狀態的時候可使用getter,至關於組件中的computed,getter中接受state做爲第一個參數

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)

    }

  }

})

 

//Getter 也能夠接受其餘 getter 做爲第二個參數

getters: {

  // ...

  doneTodosCount: (state, getters) => {

    return getters.doneTodos.length

  }

}

store.getters.doneTodosCount // -> 1

訪問方式:

屬性訪問:將store放入全局組件中後能夠經過this.$store.getters.doneTodosCount來訪問store中的計算屬性

方法訪問:經過讓 getter 返回一個函數,來實現給 getter 傳參

getters: {

  // ...

  getTodoById: (state) => (id) => {

    return state.todos.find(todo => todo.id === id)

  }

}

store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

改善:getter中也會出現相似state中的問題,vuex一樣提供了輔助函數mapGetter

3、Mutation:vuex中的‘method’

不直接在state中改變狀態是由於統一使用mutation來改變能夠更好的追蹤到狀態的變化

組建中經過store.commit(vue中的方法名)來調用vuex統一管理的方法

Mutation中的方法中第一個是state,第二個能夠加入形參,在訪問的時候commit中第二個放入實參

Mutation必須是同步的函數

你能夠在組件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 輔助函數將組件中的 methods 映射爲 store.commit 調用(須要在根節點注入 store)

4、Action:因爲mutation只能是同步的函數因此須要action來執行異步的函數

Action 提交的是 mutation,而不是直接變動狀態

const store = new Vuex.Store({

  state: {

    count: 0

  },

  mutations: {

    increment (state) {

      state.count++

    }

  },

  actions: {

    increment (context) {

      context.commit('increment')

    }

  }

})

  

你能夠調用 context.commit 提交一個 mutation,或者經過 context.state 和 context.getters 來獲取 state 和 getters

 

你在組件中使用 this.$store.dispatch('xxx') 分發 action,或者使用 mapActions 輔助函數將組件的 methods 映射爲 store.dispatch 調用(須要先在根節點注入 store)

Action能夠經過promise來組合多個action來處理更加複雜的異步流程

表單中的雙向綁定

  假設表單中綁定的是在計算屬性返回的屬於vuex store的對象,用戶輸入的時候就會試圖去直接改變vuex中的狀態,而通常不能直接修改vuex中的狀態

  方法一:須要經過mutation去修改:給 <input> 中綁定 value,而後偵聽 input 或者 change事件

  

<input :value="message" @input="updateMessage">
// ...
computed: {
  ...mapState({
    message: state => state.obj.message
  })
},
methods: {
  updateMessage (e) {
    this.$store.commit('updateMessage', e.target.value)
  }
}
//下面是 mutation 函數:

// ...
mutations: {
  updateMessage (state, message) {
    state.obj.message = message
  }
}

 

  方法二:在計算屬性的set中調用mutation來改變當前值,並在mutation中取得新的值進行賦值

  

<input v-model="message">
// ...
computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}
相關文章
相關標籤/搜索