当前位置:首页 > JavaScript

用原生js实现vuex

2026-01-31 04:25:40JavaScript

使用原生 JavaScript 实现 Vuex 的核心功能

Vuex 是一个状态管理库,其核心功能包括状态管理、响应式数据、提交 mutations 和分发 actions。以下是使用原生 JavaScript 实现 Vuex 核心功能的代码示例。

用原生js实现vuex

实现 Store 类

class Store {
  constructor(options = {}) {
    this._state = options.state || {};
    this._mutations = options.mutations || {};
    this._actions = options.actions || {};
    this._getters = options.getters || {};

    this.getters = {};
    this._subscribers = [];

    this._makeGettersReactive();
    this._makeStateReactive();
  }

  _makeStateReactive() {
    this._state = new Proxy(this._state, {
      get: (target, key) => {
        return target[key];
      },
      set: (target, key, value) => {
        target[key] = value;
        this._notifySubscribers();
        return true;
      }
    });
  }

  _makeGettersReactive() {
    Object.keys(this._getters).forEach(getterName => {
      Object.defineProperty(this.getters, getterName, {
        get: () => this._getters[getterName](this.state),
        enumerable: true
      });
    });
  }

  get state() {
    return this._state;
  }

  commit(type, payload) {
    if (this._mutations[type]) {
      this._mutations[type](this.state, payload);
      this._notifySubscribers();
    } else {
      console.error(`Mutation "${type}" not found`);
    }
  }

  dispatch(type, payload) {
    if (this._actions[type]) {
      return this._actions[type](this, payload);
    } else {
      console.error(`Action "${type}" not found`);
    }
  }

  subscribe(fn) {
    this._subscribers.push(fn);
  }

  _notifySubscribers() {
    this._subscribers.forEach(sub => sub(this.state, this.state));
  }
}

使用示例

const store = new Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state, payload) {
      state.count += payload;
    }
  },
  actions: {
    incrementAsync({ commit }, payload) {
      setTimeout(() => {
        commit('increment', payload);
      }, 1000);
    }
  },
  getters: {
    doubleCount: state => state.count * 2
  }
});

// 使用 store
store.commit('increment', 1);
console.log(store.state.count); // 1
console.log(store.getters.doubleCount); // 2

store.dispatch('incrementAsync', 1);
setTimeout(() => {
  console.log(store.state.count); // 2
}, 1500);

store.subscribe((mutation, state) => {
  console.log('State changed:', state);
});

实现响应式状态

上述代码使用 Proxy 实现了状态的响应式更新。当状态变化时,会通知所有订阅者。这种方式模拟了 Vue 的响应式系统。

实现模块化

如果需要模块化功能,可以扩展 Store 类以支持模块:

class Module {
  constructor(rawModule) {
    this.state = rawModule.state || {};
    this._rawModule = rawModule;
    this._children = {};
  }

  get namespaced() {
    return !!this._rawModule.namespaced;
  }

  addChild(key, module) {
    this._children[key] = module;
  }

  getChild(key) {
    return this._children[key];
  }
}

class ModuleCollection {
  constructor(rawRootModule) {
    this.register([], rawRootModule);
  }

  register(path, rawModule) {
    const newModule = new Module(rawModule);
    if (path.length === 0) {
      this.root = newModule;
    } else {
      const parent = this.get(path.slice(0, -1));
      parent.addChild(path[path.length - 1], newModule);
    }

    if (rawModule.modules) {
      Object.keys(rawModule.modules).forEach(key => {
        this.register(path.concat(key), rawModule.modules[key]);
      });
    }
  }

  get(path) {
    return path.reduce((module, key) => {
      return module.getChild(key);
    }, this.root);
  }
}

完整实现

结合模块化的完整实现需要考虑命名空间、模块状态合并等复杂情况。以上代码提供了 Vuex 核心功能的简化实现,可以根据需要进一步扩展。

用原生js实现vuex

标签: jsvuex
分享给朋友:

相关文章

vue实现js休眠

vue实现js休眠

Vue 中实现 JavaScript 休眠 在 Vue 中实现 JavaScript 休眠通常需要使用异步方式,以避免阻塞主线程。以下是几种常见方法: 使用 setTimeout 和 Pro…

js实现

js实现

实现 JavaScript 功能的方法 在 JavaScript 中实现特定功能通常涉及多个步骤。以下是常见的实现方法: 基础语法和变量声明 使用 let 或 const 声明变量: let co…

js实现轮播

js实现轮播

实现轮播图的基本思路 轮播图的核心逻辑是通过定时切换展示的图片或内容,通常结合左右滑动按钮和指示器(小圆点)增强交互性。以下是基于原生JavaScript的实现方法。 HTML结构 构建轮播图的HT…

js实现图片上传

js实现图片上传

图片上传的基本实现 使用HTML的<input type="file">元素配合JavaScript的File API可以实现图片上传功能。HTML部分需要创建一个文件选择输入框和一个用于…

js实现乘

js实现乘

JavaScript 实现乘法运算 在 JavaScript 中实现乘法运算可以通过多种方式完成,包括基本运算符、函数封装以及高级算法(如大数乘法)。以下是几种常见方法: 使用基本乘法运算符 Jav…

js实现求导

js实现求导

实现数值求导的方法 在JavaScript中实现求导通常采用数值方法,因为JavaScript不是符号计算语言。以下是常见的数值微分方法: 中心差分法 中心差分法提供较高精度的导数近似:…