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的思维处理表单


  • 测试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

你可能感兴趣的:(vue+,/,react+,/,angular+)