手写Vuex (更新中)

一、Vuex的核心模块

1. state

state状态,作用是用来存储 全局 的状态,目的是方便每个组件之间的通信,从而做到数据的统一管理。

2. getters

getters和vue中的computed计算属性是跟相似,都是对数据进一步加工/过滤,从而得到最终结果。

3. mutations

mutations的目的是做数据的同步赋值,官方推荐使用该方法进行同步赋值,而不推荐直接使用 $store.state.xx = xx。个人的看法,如果直接赋值的化,看似可以直接赋值成功,存在一些缺陷,我们没办法在赋值的基础上做其他的扩展,比如我不单单需要赋值,我要求在赋值的时候同时保存所有的赋值记录,方便调试工具的调试,那么此时使用mutations的优点便可以体现出来。

4. actions

actions的目的是用来做数据的异步赋值,可以在actions中调用mutations来赋值。

5. modules

modules的目的是用来做模块的划分,当项目过于复杂的时候,我们就可以使用modules来进行管理。

二、Store类

let Vue;
class Store {
    constructor(opts) {
        this._state = new Vue({
            data: {
                state: opts.state
            }
        });

        let getters = opts.getters;
        this.getters = {};
        Object.keys(getters).forEach((val)=>{
            Object.defineProperty(this.getters, val, {
                get:()=>{
                    return getters[val](this.state);
                }
            })
        })

        let mutations = opts.mutations;
        this.mutations = {};
        Object.keys(mutations).forEach((val)=>{
            this.mutations[val] = mutations[val];
        })

        let actions = opts.actions;
        this.actions = {};
        Object.keys(actions).forEach((val)=>{
            this.actions[val] = actions[val];
        })
    }

    get state() {
        return this._state.state;
    }

    commit = (funName, params)=>{
        // 在mutations中找到funName中对应的函数并且执行
        this.mutations[funName](this.state, params);
    }

    dispatch(funName, params) {
        this.actions[funName](this, params);
    }
}

const install = (vue) =>{
    Vue = vue;
    vue.mixin({
        beforeCreate() {
            // 将store挂载到唯一的根组件上
            if(this.$options && this.$options.store) {
                this.$store = this.$options.store;
            } else {
                this.$store = this.$parent && this.$parent.$store;
            }
        },
    })
}

export default {
    Store,
    install
}

分析:

  • 我们需要一个给Vue.use方法提供一个install方法,用来做Vuex的安装,即目的是用来将store挂载到Vue的根组件上,从而达到Vuex的全局使用。
  • 使用Vue.mixin全局混入方法,将每个组件的$store指向根组件。
  • commit和dispatch是用来触发mutations和actions的方法,基本的原理就是发布订阅,需要特别数以一点this的指向问题。
  • 我们发现this._state是Vue的实例对象,为什么要这样做?原因很简单,因为Vuex是一个响应式的插件,我们需要结合Vue来实现响应式原理,二Vue实例的对象具有响应式的功能,从而可以满足Vuex的响应式原理,达到页面和数据的同步更新。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值