Vue原理解析:手写状态管理器 —— Vuex

由于时间问题,暂时先把代码完整的贴上来,感兴趣的朋友可以自行研究或收藏。等我那时有时间的时候,对专栏文章进行排序,并逐一讲解代码

一、对外暴露的入口文件index.js

import Vue from "vue";
import Vuex from "./kvuex";

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        count: 1
    },
    mutations: {
        add(state) {
            state.count++;
        }
    },
    actions: {
        add({commit}) {
            setInterval(() => {
                commit("add");
            }, 1000)
        }
    },
    getters: {
        doubleCounter: state => {
            return state.count * 2;
        }
    }
})

二、状态管理器处理实例

let Vue;

class Store {
    constructor(options) {
        // 1.获取选项内容
        const { state, getters, mutations, actions, modules } = options;

        // 2.保存选项
        this._actions = actions || {};
        this._mutations = mutations || {};

        // 3.动态设置getter属性
        this.getters = {}
        const computed = {}
        Object.entries(getters).forEach(([key, fn]) => {
            computed[key] = () => {
                return fn(this.state, this.getters);
            };
            Object.defineProperty(this.getters, key, {
                get: () => this._vm[key]
            })
        });

        // 4.做响应式状态state属性
        this._vm = new Vue({
            data: {
                // $$的变量不会走依赖收集的过程
                $$state: options.state
            },
            computed
        });

        // 5.上下文绑定 - 指定commit, dispatch 函数的执行环境
        this.commit = this.commit.bind(this);
        this.dispatch = this.dispatch.bind(this);
    }

    // 暴露属性的访问接口
    get state() {
        return this._vm._data.$$state;
    }

    // 注意:Setter函数中必须要有一个参数,即使用不到
    set state(v) {
        console.error("please use replaeState to reset state");
    }

    commit(type, payload) {
        // 获取mutations
        if (!this._mutations[type]) {
            console.error("unknown mutation type");
        }
        // data都挂载在实例的 _data 属性上。直接拿不到。 在模板中能直接拿到
        this._mutations[type](this.state, payload);
    }

    // 发起函数执行的方法
    dispatch(type, payload) {
        // 获取actions
        if (!this._actions[type]) {
            console.error("unknown actions type");
        }
        this._actions[type](this, payload);
    }
}

function install(_Vue) {
    Vue = _Vue;
    // 挂载store
    Vue.mixin({
        beforeCreate() {
            if (this.$options.store) {
                Vue.prototype.$store = this.$options.store;
            }
        }
    });
}

export default { Store, install }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值