Vuex 理解學習


1.Vuex 是什么?

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

 個人理解:管理應用的所有組件的狀態,我們可以理解為在所有組件中都能用到的一個變量,而且這個變量狀態要在發生變化后保持一致。

2.使用Vuex基礎

 1、安裝依賴命令:npm install vuex --save   可以簡寫為: npm i vuex -S

 2、引入和使用

  import Vue from 'vue'

  import Vuex from 'vuex'

  Vue.use(Vuex)

3.具體使用

 1、創建一個 store,里面有一個主文件index.js。僅需要提供一個初始 state 對象和一些 mutation

 如文檔所說這個應用包含以下幾個部分:

  • state,驅動應用的數據源;
  • view,以聲明方式將 state 映射到視圖;
  • actions,響應在 view 上的用戶輸入導致的狀態變化。

 食用前請先引入如2-2

 export default new Vuex.Store({

  state: {

    count: 0
  },
  mutations: {
    increment: state => state.count++,
    decrement: state => state.count--
  }
 })

 2.在main.js中引入這個store的indexjs

  import store from './store/index'

  new Vue({
    el: '#app',
    router,
    store,   //將store掛載到vue上,通過在根實例中注冊 store 選項,該 store 實例會注入到根組件下的所有子組件中,且子組件能通過 this.$store訪問到
    template: '<App/>',
    components: { App }
  })

 3.在組件中調用

  <div id="app">
    <p>{{ count }}</p>
    <p>
      <button @click="increment">+</button>
      <button @click="decrement">-</button>
    </p>
  </div>

  new Vue({
    el: '#app',
    computed: {
      count () {
        return this.$store.state.count
      }
    },
    methods: {
      increment () {
        this.$store.commit('increment')
      },
      decrement () {
        this.$store.commit('decrement')
      }
    }
  })

 4.最簡單的對vuex中的count進行加減就已經實現了,那么問題來了,竟然使用state和mutation就能實現,那action和getter這些到底有什么用呢?

 

4.分析一波

  1.state:里面是我們的數據源,也就是我們使用的變量

  2.mutations:則是我們的操作,也就是修改狀態的操作

 

  @state:組件的數據展示方法

    1、計算屬性中computed:

    computed:{

      count () {
        return this.$store.state.count
      }

    }

    2、計算屬性中computed,mapState 輔助函數

    import {mapState} from 'vuex';

    computed:{

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

      ...mapState({

        count:state=>state.count

      })

    }

    3、計算屬性中computed,mapState 輔助函數

    import {mapState} from 'vuex';

    computed:{

      // 映射 this.count 為 store.state.count
      ...mapState(["count"])
    }

 

未完待續。。。。。

  

  @mutations:修改狀態的操作,主要是通過--this.$store.commit('decrement')

    @1.<button @click="increment">+</button>  

    @2.increment () {
      this.$store.commit('increment')
    }

    @3.mutations: {
      increment: state => state.count++,
      decrement: state => state.count--
    }

 

 當然this.$store.commit也可以傳額外的參數比如說--this.$store.commit('increment' ,10 )

   ---文檔中說即 mutation 的 載荷(payload),但在大多數情況下,載荷應該是一個對象,,這樣可以包含多個字段並且記錄的 mutation 會更易讀 

 

    @1.<button @click="increment">+</button>  

    @2.increment () {
      this.$store.commit('increment',m)
    }

    @3.mutations: {
      increment: (state,m) => state.count+=m,
      decrement: state => state.count--
    }

 

 在組件中提交 Mutation---什么意思呢? 

   文檔上說:1.使用 this.$store.commit('xxx') 提交 mutation;

        2.使用 mapMutations 輔助函數將組件中的 methods 映射為 store.commit 調用

   上面例子使用的是this.$store.commit('xxx') 提交 mutation,現在我們使用 mapMutations 輔助函數將組件中的 methods 映射為 store.commit 調用

    @1.<button @click="increment">+</button>  

      @2.mutations: {

      increment: (state,m) => state.count+=m,
      decrement: state => state.count--
    }

    @3.import { mapMutations } from 'vuex' 

    methods:{
      ...mapMutations(
        [ 'increment','decrement' ]
      )

    }

  這樣看起來是不是感覺更好了呢。。。 

 5.使用常量替代 Mutation 事件類型---mutation.type.js

  // mutation-types.js   export const SOME_MUTATION = 'SOME_MUTATION' 
  // store.js   import Vuex from 'vuex'   import { SOME_MUTATION } from './mutation-types'   const store = new Vuex.Store({   state: { ... },   mutations: {   // 我們可以使用 ES2015 風格的計算屬性命名功能來使用一個常量作為函數名   [SOME_MUTATION] (state) {   // mutate state   }   }   })

  Mutation 必須是同步函數, mutation 中混合異步調用會導致你的程序很難調試。例如,當你能調用了兩個包含異步回調的 mutation 來改變狀態,你怎么知道什么時候回調和哪個先回調呢?這就是為什么我們要區分這兩個概念,為了處理異步操作,讓我們來看一看 Action。 

 

 6.Action 類似於 mutation,不同在於:

  • Action 提交的是 mutation,而不是直接變更狀態。
  • Action 可以包含任意異步操作。

    actions: {  

      addAction(context){
        context.commit('add',10)
      },

    //ES2015 的 參數解構 來簡化代碼
      reduceAction({commit}){
        commit('reduce')
      }

     } 

  1.分發 Action

    1.Action 通過 store.dispatch 方法觸發:

      store.dispatch('increment')

    2.Actions 支持同樣的載荷方式和對象方式進行分發:
    
    // 以載荷形式分發 store.dispatch('incrementAsync', { amount: 10 })
    // 以對象形式分發 store.dispatch({ type: 'incrementAsync', amount: 10 })
 

  2.在組件中分發 Action

    1.使用 this.$store.dispatch('xxx') 分發 action;

    2.使用 mapActions 輔助函數將組件的 methods 映射為 store.dispatch 調用

    @1.<button @click="addAction">+</button>  

    @2.import { mapActions } from 'vuex'   

    methods:{
      ...mapActions(
        [ 'addAction','reduceAction' ]
      )

    }   

    @3.actions:{
      addAction(context){
        context.commit('add')
      },
      reduceAction({commit}){
        commit('reduce')
      }
    } 

  3.組合 Action----這部分本人沒有理解透,就不誤人子弟了

   想了解請看文檔 https://vuex.vuejs.org/zh-cn/actions.html

 

   

 7.Getter----可以認為是 store 的計算屬性。

   解釋:就像計算屬性一樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變才會被重新計算。 

    @1.<button @click="addAction">+</button>  

    @2.import { mapGetters from 'vuex'   

     computed: {

      // 使用對象展開運算符將 getter 混入 computed 對象中

      ...mapGetters(["count"])

    }

    @3.var getters={
      count:function(state){
        return (state.count<10 && state.count>0)?'0'+state.count:state.count;
      }
    }

 8.Module

   1.不多說,上代碼

   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 的狀態

 

   2.本來是 this.$store.state.count =》this.$store.state.a.count

    computed:{
      // ...mapState(["count"]),
      count () {
        return this.$store.state.a.count
      },
      // ...mapState({
        // count:state=>state.a.count //理解為傳入state對象,修改state.count屬性
      // })
    }

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM