1. 程式人生 > >Vuex ~ 專門為vue.js設計的集中式狀態管理架構

Vuex ~ 專門為vue.js設計的集中式狀態管理架構

state 原來 管理工具 t對象 包管理工具 emp UC maps fault

狀態:data中的屬性需要共享給其他vue組件使用的部分(即data中需要共用的屬性) 1、初識vuex直接來個小demo   下面操作都是基於vue-cli,如果不了解先學習下vue-cli   利用npm包管理工具,進行安裝 vuex。     npm install vuex --save   新建一個vuex文件夾(這個不是必須的),並在文件夾下新建store.js文件,文件中引入我們的vue和vuex。     import Vue from ‘vue‘;     import Vuex from ‘vuex‘;   使用我們vuex,引入之後用Vue.use進行引用。     Vue.use(Vuex);   通過以上操作,vuex就算引用成功了      直接來個demo,在vue-cli的src目錄下新建一個文件夾vuex,並在此文件夾下新建一個store.js文件;直接上demo   
現在我們store.js文件裏增加一個常量對象
        const state={
            count:1
        }
    
    用export default 封裝代碼,讓外部可以引用。
        export default new Vuex.Store({
            state
        })
    
    新建一個vue的模板,xxx.vue。在模板中我們引入我們剛建的store.js文件,
    並在模板中用{{$store.state.count}}輸出count 的值。
        <template>
            <div>
                <h2>{{msg}}</h2>
                <hr/>
                <h3>{{$store.state.count}}</h3>
            </div>
        </template>
        <script>
            import store from ‘@/vuex/store‘
            export default{
                data(){
                    return{
                        msg:‘Hello Vuex‘
                    }
                },
                store   //註意要先引用下
            }
        </script>
    在store.js文件中加入兩個改變state的方法。

        const mutations={
            //改變state的數值
            add(state){
                state.count++;
            },
            reduce(state){
                state.count--;
            }
        }
        export default new Vuex.Store({
            state,
            mutations
        })

    
    在xxx.vue模板中加入兩個按鈕,並調用mutations中的方法
        <div>
            <button @click="$store.commit(‘add‘)">+</button>
            <button @click="$store.commit(‘reduce‘)">-</button>
        </div>
    這樣進行預覽就可以實現對vuex中的count進行加減了
2.state訪問狀態對象
上面例子中 const state ,就是訪問狀態對象,也就是兄弟組件間的共享值。
    下面是狀態對象賦值給內部對象,也就是把stroe.js中的值,賦值給我們模板裏data中的值

    三種賦值方式:
        一、通過computed的計算屬性直接賦值
            computed:{
                count(){
                    return this.$store.state.count;
                }
            }
            模板調用:{{count}}

            缺點:當一個組件需要獲取多個狀態時候,將這些狀態都聲明為計算屬性會有些重復和冗余。
        
        二、通過mapState的《對象》來賦值
            import {mapState} from ‘vuex‘;
            然後還在computed計算屬性裏寫如下代碼:
                computed:mapState({
                    count:state=>state.count
                })

        三、通過mapState的《數組》來賦值
            computed:mapState(["count"])

3.Mutations修改state狀態

1. mutations  相當於一個對象,對象裏面放的是事件類型相對應的回調函數,作用就是進行狀態更改;簡單理解就相當於一個事件註冊

    2. $store.commit()  //模板中調用mutations 裏面的事件函數

    傳值:只需要在Mutations裏再加上一個參數,並在commit的時候傳遞就就可以了
        const mutations={
            add(state,n){
                state.count+=n;
            },
            reduce(state){
                state.count--;
            }
        }

        在XXX.vue裏修改按鈕的commit( )方法傳遞的參數,我們傳遞10,意思就是每次加10.
            <p>
                <button @click="$store.commit(‘add‘,10)">+</button>
                <button @click="$store.commit(‘reduce‘)">-</button>
            </p>
    
    
    模板獲取Mutations方法
        實際開發中我們也不喜歡看到$store.commit( )這樣的方法出現,我們希望跟調用模板裏的方法一樣調用。
        例如:@click=”reduce”   就和沒引用vuex插件一樣。
        要達到這種寫法,只需要簡單的兩部就可以了:

        在模板XXX.vue裏用import 引入我們的mapMutations:
            1.在模板XXX.vue裏用import 引入我們的mapMutations:
                import { mapState,mapMutations } from ‘vuex‘;

            2.在模板的script標簽裏添加methods屬性,並加入mapMutations
                methods:mapMutations([
                    ‘add‘,‘reduce‘
                ]),

            3.通過上面兩步後調用(註意額外參數直接寫上)
                <button @click="add(10)">+</button>

4.getters計算過濾操作

getters從表面是獲得的意思,可以把他看作在《 獲取數據之前 》進行的一種再編輯(註意模板顯示getters操作後的值)
    相當於對數據的一個過濾和加工,可以把它看作store.js的計算屬性(類似於computed)
    getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變才會被重新計算

    《1》基本用法:
        首先要在store.js裏用const聲明我們的getters屬性。
            const getters = {
                count:function(state,getters){
                    return state.count +=getters.params_getter;
                },
                params_getter:function(){
                    return 1000
                }
            }
            參數:
                state : 
                getters : getters.xxx 來傳遞其他 getters 中的數據

        寫好了gettters之後,我們還需要在Vuex.Store()裏引入
            export default new Vuex.Store({
                state,mutations,getters
            })
        
        在store.js裏的配置算是完成了,我們需要到模板頁對computed進行配置
        在vue 的構造器裏邊只能有一個computed屬性,如果你寫多個,只有最後一個computed屬性可用,
        所以要對computed屬性進行一個改造。
        改造時我們使用ES6中的展開運算符”…”。
            computed:{
                ...mapState(["count"]), //相當於一個擴展
                count(){
                    return this.$store.getters.count;
                }
            }
        
    《2》用mapGetters簡化模板寫法:
        都知道state和mutations都有map的引用方法把我們模板中的編碼進行簡化,我們的getters也是有的
        首先用import引入我們的mapGetters
            import { mapState,mapMutations,mapGetters } from ‘vuex‘;
        在computed屬性中加入mapGetters
            ...mapGetters(["count"])

5.actions異步修改狀態

actions和之前講的Mutations功能基本一樣
    不同點是,
        1.actions 提交的是 mutation,而不是直接變更狀態。
        2.actions是異步的改變state狀態,而Mutations是同步改變狀態。

    在store.js中聲明actions
        actions是可以調用Mutations裏的方法的,在actions裏調用add和reduce兩個方法
        以下是事件註冊的兩種方式:
            const actions ={
                addAction(context){
                    context.commit(‘add‘,10)
                },
                reduceAction({commit}){
                    //由於context 與 store 實例具有相同方法和屬性,所以可以提交mutation
                    commit(‘reduce‘)
                }
            }
        
        在actions裏寫了兩個方法addAction和reduceAction,在方法體裏,我們都用commit調用了Mutations裏邊的方法。
            context:上下文對象,這裏你可以理解稱store實例本身。
            {commit}:直接把commit對象傳遞過來,可以讓方法體邏輯和代碼更清晰明了。
        
        
        模板中的使用
            <p>
                <button @click="addAction">+</button>
                <button @click="reduceAction">-</button>
            </p>
            改造一下我們的methods方法,首先還是用擴展運算符把mapMutations和mapActions加入
            methods:{
                ...mapMutations([  
                    ‘add‘,‘reduce‘
                ]),
                ...mapActions([‘addAction‘,‘reduceAction‘])
            }
        
            用import把我們的mapActions引入才可以使用
                import { mapState,mapMutations,mapGetters,mapActions } from ‘vuex‘;
        
        增加異步檢驗
            演示actions的異步功能,我們增加一個計時器(setTimeOut)延遲執行
                setTimeOut(()=>{context.commit(reduce)},3000);
                console.log(‘我比reduce提前執行‘);

6.module模塊組(狀態管理器的模塊組操作)

隨著項目的復雜性增加,我們共享的狀態越來越多,這時候我們就需要把我們狀態的各種操作進行一個分組,分組後再進行按組編寫。
    聲明模塊組:
        在vuex/store.js中聲明模塊組,我們還是用我們的const常量的方法聲明模塊組。代碼如下:
            const moduleA = {
                state: { ... },
                mutations: { ... },
                actions: { ... },
                getters: { ... }
            }
            const moduleB = {
                state: { ... },
                mutations: { ... },
                actions: { ... }
            }
        聲明好後,我們需要修改原來 Vuex.Stroe裏的值:
            const store = new Vuex.Store({
                modules: {
                    a: moduleA,
                    b: moduleB
                }
            })
        
        store.state.a // -> moduleA 的狀態
        store.state.b // -> moduleB 的狀態
    
    在模板中使用:
        現在我們要在模板中使用count狀態,要用插值的形式寫入
            <h3>{{$store.state.a.count}}</h3>
        如果想用簡單的方法引入,還是要在我們的計算屬性中rutrun我們的狀態。寫法如下:
            computed:{
                count(){
                    return this.$store.state.a.count;
                }
            }

  

              

Vuex ~ 專門為vue.js設計的集中式狀態管理架構