当前位置:首页 > 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 的响应式系统。

用原生js实现vuex

实现模块化

如果需要模块化功能,可以扩展 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 核心功能的简化实现,可以根据需要进一步扩展。

标签: jsvuex
分享给朋友:

相关文章

js实现vue路由

js实现vue路由

Vue 路由的基本实现 在 Vue.js 中实现路由功能通常使用 Vue Router 库。Vue Router 是 Vue.js 官方的路由管理器,用于构建单页面应用(SPA)。 安装 Vue R…

js实现吸色

js实现吸色

使用Canvas实现吸色功能 通过Canvas的getImageData方法获取像素颜色数据。创建一个Canvas元素,将目标图像绘制到Canvas上,通过鼠标事件获取坐标对应的颜色值。 const…

js实现搜索

js实现搜索

实现搜索功能的方法 在JavaScript中实现搜索功能可以通过多种方式完成,以下是几种常见的实现方法。 使用数组的filter方法 通过数组的filter方法可以筛选出符合条件的数据项。假设有一个…

js实现下拉刷新

js实现下拉刷新

监听触摸事件 通过监听 touchstart、touchmove 和 touchend 事件来检测用户下拉手势。记录触摸起始位置和移动距离。 let startY = 0; let curr…

js实现显示隐藏

js实现显示隐藏

显示隐藏的实现方法 在JavaScript中,实现元素的显示和隐藏可以通过多种方式完成。以下是几种常见的方法: 修改CSS的display属性 通过改变元素的display属性可以在none(隐藏)…

js实现按钮点击

js实现按钮点击

实现按钮点击的JavaScript方法 HTML按钮元素 在HTML中创建按钮元素,为其添加id或class以便JavaScript选择: <button id="myButton">点…