vuex 深入實踐

Vuex 核心模塊

state

  • 單一狀態樹,用一個對象就包含了全部的應用層級狀態
  • mapState 當一個組件需要多個狀態的時候, 將這些狀態都聲明爲計算屬性,會有些重複和冗餘
  • 對象展開符號 …mapState({})
import {mapState} from 'vuex'

export default {
    // mapState要寫到computed上面 ,用了vuex之後就要把data給忘了.
    computed: mapState({
        count: state => state.count,
        countAlias: "count",
        countPlusLocalState(state) {
            return state.count + this.localCount
        }
    })
    // ...mapState({count}) 擴展函數符
}

getters

  • 從store 中的state中派生出一些狀態
  • mapGetters 輔助函數,僅僅是將store中的getters映射到局部計算屬性
  • getters (可以認爲是store的計算屬性)
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)
        }
    }
})
    // use:
    ,computed:{
        doneTodosCount(){
            // this.$store就是vuex 上面的
           return this.$store.getters.doneTodos
        }
    }
    // use:
    ,computed:{
        ...mapGetters([
            'doneTodos'
        ])
    }

mutations

  • 更改Vuex的store中的狀態,的唯一方式是提交mutation(不能直接調用句柄,必須通過觸發)
  • mutations 就是vue 中的methods
  • 每一個mutation都有一個字符串的事件類型(type)和一個回調函數(handler)
  • 使用常量代替mutation事件類型
  • mutation必須是同步函數
// mutation-type.js
export const SOME_MUTATION='SOME_MUTATION'

// store.js
import {SOME_MUTATION} from './mutation-type'
const store=new Vuex.Store({
    state:{...},
    mutations:{
        // 接受一個常量作爲Objeck對象的key.是es6的寫法
        [SOME_MUTATION](state){
            //mutate state
        }
    }
})

然後調用

// use:
import {mapMutations} from 'vuex'
import {SOME_MUTATION} from './mutation-type'
export default {
    methods:{
        test(){
            this.$store.commit(SOME_MUTATION)
        },
        ...mapMutations([
            'SOME_MUTATION'
            // 映射thisincrement()爲this.$store.commit('SOME_MUTATION')
        ])
    }
}

actions

  • action提交的是mutation
  • action可以包含任何異步操作
  • mapActions輔助函數將組建的methods映射爲store.dispatch調用
  • view->store.dispatch(‘increment’)
  • action->commit(‘someMutation’)
actions:{
    async actionA({commit}){
        commit('gotDate',await getDate())
    },
    async actionB({dispatch,commit}){
        await dispatch('actionA')//等待actionA完成
        //commit 可以帶數據過去
        commit('gotOtherData',await getOtherData())
    }

}
// use:
import {mapActions} from 'vuex'
export default {
    methods:{
        test(){
            store.dispatch('actionB')
        },
        ...mapActions([
            'actionB'
            //映射this.incrment()
            // this.$store.dispatch('actionB')
        ])
    }
}

modules

  • vuex運行我們將store分割到模塊(module).每個模塊擁有自己的state,mutation,action,getters,甚至是嵌套子模塊–從上至下進行類似的分割
  • store創建之後,你可以使用store,registerModule方法註冊模塊
const moduleA={
    state:{},
    mutations:{},
    actions:{},
    getters:{}
}
const moduleB={
    state:{},
    mutations:{},
    actions:{},
    getters:{}
}

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

附:

//動態註冊一個module
store.registerModule('moduleC',{})

plugins

  • vuex的store 接受plugins選項,這個選項暴露出每次mutation的鉤子,vuex插件就是一個函數,他接收sotre作爲唯一參數
  • 在插件中不允許直接修改狀態–類似於組建,智能通過提交mutation來觸發變化;
  • 自定義的狀態快照
const myPlugin = store => {
    // 當store 初始化後調用
    store.subscribe((mutation,state)=>{
        // 每次mutation之後調用
        // mutation的格式爲{type,payload}
    })
}
// use
const store=new Vuex.Store({
    plugins:[myPlugin]
})

還有啥?

  • Vuex的思維處理表單

    <input :value="message" @input="updateMessage">
  • 測試Action需要增加一個mocking服務層, 測試文件中用mock服務響應API調用,爲例便於解決mock依賴,可以用webpack和inject-loader打包測試文件;
  • Hot MOdule Replacement API, Vuex支持在開發過程中熱重載mutation,mudules,actions 和getters.
// 測試Actions 演示
import {expect} from 'chai'
const actionsInjector=require('inject!./actions')

const actions=actionsInjector({
    '../api/shop':{
        getProducts(cb){
            setTimeout(()=>{
                cb([/*mocked response*/])
            },100)
        }
    }
})
// 測試代碼
describe('actions',()=>{
    it("getAllProducts",done=>{
        testAction(actions.getAllProducts,[],{},[
            {type:'REQUEST_PRODUCTS'},
            {type:'RECEIVE_PRODUCTS',payload:{}}
        ],done)
    })
})

vuex-router-sync

  • vue 管理視圖的
  • vuex 管理數據元
  • vuex-router-sync 是鏈接vuex和vue-router
import {sync} from 'vuex-router-sync'
import store from './vuex/store'
import router from './router'

sync(store,router)
this.$store.state.route.path
this.$store.state.route.params
this.$store.state.route.query
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章