1. 程式人生 > >VUEX的簡單運用

VUEX的簡單運用

什麼是vuex

Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 也整合到 Vue 的官方除錯工具 devtools extension,提供了諸如零配置的 time-travel 除錯、狀態快照匯入匯出等高階除錯功能

好的 完全看不懂

簡單來講,我們可以把一些貨物一起放在一個倉庫之中,可以讓我們與貨物的距離只有一條通道,當我們去存取貨物的時候,裡面的東西是共有的,大家都能公用,誰都可以往裡面進行存取操作

安裝、使用 vuex

npm install vuex --save

在src目錄下手動建立目錄檔案 vuex/store.js

在main.js中配置

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import vuex from 'vuex'
    Vue.use(vuex)
    Vue.config.productionTip = false
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      components: { App },
      template: '<App/>'
    })

在vuex/store.js中配置

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);    //必不可少
    const state={
        count:1
    }
    export default new vuex.Store({  //暴露vuex.store
        state
    })

在需要呼叫的元件中引入

    import store from '@/vuex/store'
    export default {
        store  //一定要在例項中註冊
    }

獲取store中的state

    <template>
        <div>
            {{$store.state.count}}  //1
        </div>
    </template>

此處提前說明一下moudle 模組組,隨著資料元件狀態越來越多,同寫一個檔案不好維護

新建一個js 暴露出來

    export default {
        state:{
            count:1
        }
    }

在store.js中匯入

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    import states from './state'
    export default new vuex.Store({
        modules:{      //此引數固定
          state:states
        }
    })

{{$store.state.state.count}} //1

其實只是相當於多了一層匯入,方便我們呼叫維護狀態

回到開始

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    const state={
        count:1
    }
    export default new vuex.Store({
        state
    })

簡單改變state

<template>
    <div>
        {{$store.state.count}}
        <p>
            <button @click="change">Change</button>
        </p>
    </div>
</template>

<script>
        import store from '@/vuex/store'
        export default {
            store,
            methods:{
                change(){
                    this.$store.state.count++
                }
            }
        }
</script>

<style>

</style>

強行改變vuex的state 是流氓行為(違法)

Vuex 使用單一狀態樹——是的,用一個物件就包含了全部的應用層級狀態。至此它便作為一個“唯一資料來源 (SSOT)”而存在。這也意味著,每個應用將僅僅包含一個 store 例項。單一狀態樹讓我們能夠直接地定位任一特定的狀態片段,在除錯的過程中也能輕易地取得整個當前應用狀態的快照。

簡單粗暴理解: 我們要把我們需要做狀態管理的量放到這裡來,然後在後面的操作動它

我們有了state狀態樹,我們要改變它的狀態(值),就必須用vue指定唯一方法 mutation

更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似於事件:每個 mutation 都有一個字串的 事件型別 (type) 和 一個 回撥函式 (handler)。

簡單粗暴理解:任何不以mutation的方式改變state的值,都是耍流氓(違法)

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    const state={
        count:1
    }
    const mutations={    //簡單編輯操作state的mutations  (固定寫法)
        add(state){          //此處的state就是上面的state物件
            state.count++;
        },
        reduce(state){
            state.count--;
        }
    }
    export default new vuex.Store({
        state,mutations
    }) 

在元件中呼叫mutations

<template>
    <div>
        {{$store.state.count}}
        <p>
             <button @click="$store.commit('add')">+</button>   //此處的呼叫方法注意一下 是commit
                                                                //可不是$store.mutations.add
             <button @click="$store.commit('reduce')">-</button>
        </p>
    </div>
</template>

<script>
        import store from '@/vuex/store'
        export default {
            store,
        }
</script>

<style>

</style>

此時已經可以通過按鈕通過mutations改變state了

在渲染vue的時候,根據鉤子函式生命週期渲染不同的DOM,一般情況下我們不用直接引用,而是賦值computed

computed屬性可以在輸出前,對data中的值進行改變,我們就利用這種特性把store.js中的state值賦值給我們模板中的data值。

        export default {
            store,
            computed:{
                     count(){  //將狀態賦值給count
                       return this.$store.state.count;
                     }
            }
        }

相應的改變插值中的內容 效果不變

<template>
    <div>
        {{count}}
        <p>
             <button @click="$store.commit('add')">+</button>
             <button @click="$store.commit('reduce')">-</button>
        </p>
    </div>
</template>

此寫法稍微有些麻煩,資料多了更是繁瑣

vuex為我們提供了mapState操作

首先先引入mapState

        import store from '@/vuex/store'
        import {mapState} from 'vuex';

在computed中進行賦值 效果是一樣的 motations也可執行

           computed:mapState({
                count:state=>state.count
            })

可能箭頭函式有點懵

            computed:mapState({
                count:function(state){
                    return state.count
                }
            })

接下來設定一下引數,方法肯定有時候帶引數的嘛 在store.js中

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    const state={
        count:1
    }
    const mutations={
        add(state,n){     =>此處增加了一個引數n
            state.count+=n;
        },
        reduce(state){
            state.count--;
        }
    }
    export default new vuex.Store({
        state,mutations
    })

接下來只需要在呼叫mutation方法處傳入實參即可

<template>
    <div>
        {{count}}
        <p>
             <button @click="$store.commit('add',10)">+</button>
             <button @click="$store.commit('reduce')">-</button>
        </p>
    </div>
</template>        

類似開始的state 呼叫方法有些繁瑣 不喜歡看到$store.commit( )

模板獲取Mutations方法 vuex也為我們提供了相應的方法

        import store from '@/vuex/store'
        import {mapState,mapMutations} from 'vuex'; =>引入模板

方法 我們寫在methods中

 methods:mapMutations([
    'add','reduce'
 ]),

然後改變html 這樣就跟vue一樣啦

<template>
    <div>
        {{count}}
        <p>   
             <button @click="add(10)">+</button>
             <button @click="reduce">-</button>
        </p>
    </div>
</template>

getters計算過濾操作

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    const state={
        count:1
    }
    const mutations={
        add(state,n){
            state.count+=n;
        },
        reduce(state){
            state.count--;
        }
    }
    const getters = {
        count:function(state){
            return state.count +=100; =>類似filters 過濾得到state
        }
    }
    export default new vuex.Store({
        state,mutations,getters
    })

在元件中獲取過濾之後的state

        import store from '@/vuex/store'
        import {mapState,mapMutations} from 'vuex';
        export default {
            store,
            computed:mapState({
                count:function(state){
                    return state.count
                }
            }),
             methods:mapMutations([
                  'add','reduce'
             ]),
        }

我們先分析一下當前程式碼

我們都知道程式碼屬性相同會覆蓋,也就是我如果在寫一次coumped屬性那麼上面的原有屬性將會覆蓋,此處運用es6的擴充套件運算子進行改寫

      import store from '@/vuex/store'
        import {mapState,mapMutations} from 'vuex';
        export default {
            store,
           computed:{
              ...mapState(["count"]),
              count(){
              return this.$store.getters.count;=>此時count是過濾後的state
              }
           },
             methods:mapMutations([
                  'add','reduce'
             ]),
        }

mapState通過擴充套件運算子將$store.state.count 對映this.count 這個this 很重要,這個對映直接對映到當前Vue的this物件上。(這句話不懂也可以記一下)

此時有測試的小夥伴可能發現 count是110 110 加的 而不是10 10 加的

因為當count發生改變的時候 先通過getters過濾得到新的state(此時已經+100) 然後由mutation改變+10

用mapGetters簡化模板寫法

        import store from '@/vuex/store'
        import {mapState,mapMutations,mapGetters} from 'vuex';
        export default {
            store,
           computed:{
              ...mapState(["count"]),
              ...mapGetters(["count"])
           },
             methods:mapMutations([
                  'add','reduce'
             ]),
        }

其實這裡mapMutation也可以簡寫,我想大家知道怎麼寫了

actions非同步修改狀態

actions和之前講的Mutations功能基本一樣,不同點是,actions是非同步的改變state狀態,而Mutations是同步改變狀態。至於什麼是非同步什麼是同步這裡我就不做太多解釋了

    import Vue from 'vue'
    import vuex from 'vuex'
    Vue.use(vuex);         

    const state={
        count:1
    }
    const mutations={
        add(state,n){
            state.count+=n;
        },
        reduce(state){
            state.count--;
        }
    }
    const getters = {
        count:function(state){
            return state.count +=100;
        }
    }
    const actions ={
        addAction(context){
            context.commit('add',10)  =>之前說過 mutation方法通過 commit呼叫  忘記了可以翻翻前面哦
        },
        reduceAction({commit}){
            commit('reduce')
        }
    }
    export default new vuex.Store({
        state,mutations,getters,actions
    })

這是兩處不同的引用mutations的方法

增加actions 當然 裡面的方法名是自定義的

context — {commit}

context:上下文物件,這裡你可以理解稱store本身。
{commit}:直接把commit物件傳遞過來,可以讓方法體邏輯和程式碼更清晰明瞭。

模板中使用actions

        import store from '@/vuex/store'
        import {mapState,mapMutations,mapGetters,mapActions} from 'vuex';
        export default {
            store,
           computed:{
              ...mapState(["count"]),
              ...mapGetters(["count"])
           },
             methods:{
                 ...mapMutations(['add','reduce']),
                 ...mapActions(['addAction','reduceAction'])
             }
        }

其實寫法太簡單了 練兩下就soeasy了

呼叫非同步方法名

<template>
    <div>
        {{count}}
        <p>   
             <button @click="addAction">+</button>
             <button @click="reduceAction">-</button>
        </p>
    </div>

效果相同 因為只是操作mutation的方法 將其轉換為非同步