vuex

栏目 Vue

vuex 笔记

mapState #

如果一个组件需要获取多个状态,多个computed会重复。这时候可以使用mapState辅助函数,帮助生成computed

a.vue : mapState返回的是一个对象,可以通过 ...mapState({}) 合并

如果有matation可以通过mapMutations

import {mapState, mapMutations} from 'vuex'

export default{
    //computed: mapState(['city'])
    computed: {
        ...mapState({
            g: 'gogogo' // gogogo is a state
        })
    },
    methods: {
        ...mapMutation({})
    }
}

组件仍然使用局部状态 #

不完全依赖 vuex,状态独立的单个组件,最好还是使用局部状态。

Getter #

有些 computed方法,比如获取状态长度,会经常用到,多个组件的画,需要抽离成共享函数,然后导入。

可以使用 store的计算属性 getter,getter的返回值会缓存,依赖值变化才会重新计算。

const store = new Vuex.Store({
    state:{
        todos: [{},{}]
    },
    getters:{
        len: state => state.todo.length
    }
})

这样可以通过属性访问 store.getters.len

getter 内部也可以依赖其他getter

也可以让getter返回一个函数,可以传参

getter:{
    getId:(state) => (id)=>{
        return xxx
    }
}


store.getters.getId(2)

mapGterrs 辅助函数 #

先略

Mutation #

改变store状态的唯一方法是提交 Mutation

mutation的用法再次说明

const store = new Vuex.Store({
    state:{count:1},
    mutations:{
        add(state){state.count++}
    }
})

store.commit('add')

commit的时候也可以带参数 payload

mutations:{
    add(state, n){state.count += n}
}

store.commit('add',10)

最好是传入一个对象

对象风格提交 #

store.commit({
    type:'add',
    amount:10
})

add 方法不变

注意 #

最好store中初始化所有属性

添加新属性的时候

可以使用Vue.set(obj,'newProp',123) 也可以 state.obj={...state.obj,newProp:33}

常量表示时间类型 #

外置文件

//a.js
export const AddName = 'add'

//b.js
[AddName](){}

mutation 必须是同步函数 #

组件中提交mutation #

在组件中可以使用this.$store.commit('xx')

或者使用mapMutation

import {mapMutations} from 'vuex'
export default{
    methods: {
        ...mapMutations([
            'add', // this.add === this.$store.commit('add')
            'add1', // this.add1(num) === this.$store.commit('add1',num)
        ]),
        ...mapMutation({
            add:'add' // this.add() === this.$store.commit('add')
        })
    }
}

Action #

action 类似 mutation,不同在于

action提交的是 mutation 不是变更state action可以包含一部状态

const store = new Vuex.Store({
    state:{count:0},
    mutations:{
        add(state){
            state.count++
        }
    },
    actions:{
        add(context){
            context.commit('add')
        }
    }
})

action里的context是和store拥有相同方法和属性的对象

但不是store实例。

可以通过context.commit 也可以context.state context.getters

在action里可以使用异步。

actions:{
    addAsync({commit}){
        setTimeout(()=>{
            commit('add')
        },1000)
    }
}

action 可以通过store.dispath方法出发

store.dispath('addAsync',{})
//or
store.dispath({
    type:'addAsync',
    amout:10
})

组合Action #

actions:{
    actionA({commit}){
        return new Promise()
    }
}

store.dispath('actionA').then()

Module #

当store比较庞大臃肿的是偶,可以把store分割成 module

const moduleA = {
    state:{},
    mutations:{},
    actions:{},
    getters:{}
}
const moduleB = {}

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

store.state.a // moduleA state

模块的局部状态 #

module内部的mutation的第一个参数state是内部状态

命名空间 #

可以给 moduleA 添加namespaced:true 设置命名空间

略过一块内容。

模块动态注册 #

store创建后,可以使用store.registerModule方法注册模块。

store.registerModule('moduleA',{})

store.state.moduleA

store.unregisterModule(moduleName)

项目结构 #

必须遵从的规则

1 应用层级的状态集中到单个store 2 提交mutation是变更state的唯一方法,必须同步 3 异步逻辑封装 action 里

如果store庞大,分割action到单独文件即可。最好是吧store分割成modules