• Vue之手写 Vuex


    1. 知识储备

    1.1 Vuex 基础知识

    首先需要去官网熟悉一下基本概念。Vuex 是集中式状态管理工具。它和全局对象有两点区别,第一点是 Vuex 中的数据是响应式的,即数据变动视图也会跟着变动,第二点是 Vuex 中的数据必须显示提交才可以改变,也就是说修改数据的时候都需要显示调用提供的 commit 方法。它的核心概念有4个,其中 state 用来存放数据,getter 用来获取数据(类似于 Vue 的计算属性),mutation 用来修改数据(这个是修改数据的唯一方法),action 用来异步修改数据(注意,它需要通过 mutation 修改数据)

    1.2 Vue 基础知识

    Vuex 作为全局管理插件,需要实现跨多个组件通信的场景,所以需要使用 provide/inject 方法。Vue 和 Vuex 链接是通过插件进行的,Vuex 在实现的时候需要有 install 方法,而 Vue 通过 use 方法调用插件中的 install 方法。

    2. 源码分析

    2.1 输入

    该模块引入 inject,reactive,computed 三个方法,其中 inject 用于跨组件使用对象,这里获取到的是 new store 后生成的实例;reactive 用于将 state 中的数据变成响应式的;computed 用于 getter 获取 state 中的数据并保持响应式。

    2.2 输出

    该模块输出 useStore 和 createStore 两个方法,其中 createStore 方法可以将参数中的 state 变成响应式的,getters 响应式获取 state 中的数据并且支持多个方法,另外还支持 commit 和 dispath

    2.3 补充

    commit 方法会直接存在于 new Store 创建的实例中,这个不同于 dispatch 方法,它只存在于 Store 的实例对象中,这个是实例属性的新写法,可以参考 ES6入门

    3. 源码

    1. import { inject, reactive, computed } from "vue";
    2. const STORE_KEY = "__store__";
    3. // 组件中使用的时候调用
    4. function useStore() {
    5. return inject(STORE_KEY);
    6. }
    7. // 使用 app.use 方法的时候调用
    8. function createStore(options) {
    9. return new Store(options);
    10. }
    11. class Store {
    12. constructor(options) {
    13. this.$options = options;
    14. this._state = reactive({
    15. data: options.state(),
    16. });
    17. this._mutations = options.mutations;
    18. this._actions = options.actions;
    19. this.getters = {};
    20. // 遍历 options.getters 中的所有方法,然后放到 getters 中并使用 computed 方法保持响应性
    21. Object.keys(options.getters).forEach((name) => {
    22. const fn = options.getters[name];
    23. this.getters[name] = computed(() => fn(this.state));
    24. });
    25. }
    26. // store.state 的时候获取 data
    27. get state() {
    28. return this._state.data;
    29. }
    30. // 如果有对应的方法,则调用该方法
    31. commit = (type, payload) => {
    32. const entry = this._mutations[type];
    33. entry && entry(this.state, payload);
    34. };
    35. dispatch(type, payload) {
    36. const entry = this._actions[type];
    37. return entry && entry(this, payload);
    38. }
    39. install(app) {
    40. app.provide(STORE_KEY, this);
    41. }
    42. }
    43. export { createStore, useStore };
    44. 复制代码

    4. 总结

    通过学习手写 Vuex 的代码可以加深对官网文档的理解,同时注意平常使用的时候需要保持响应性,并且只通过 commit 方法进行显示修改数据。

  • 相关阅读:
    【送书福利-第二十八期】《AIGC:让生成式AI成为自己的外脑》
    qml 使用Shape 画图形
    C++之面向对象
    第七讲 项目的收尾代码
    element ui - el-table 表头筛选
    mysql InnoDB 事务的实现原理
    java 企业工程管理系统软件源码+Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
    kafka安装与相关配置详解
    E: Unable to locate package xxxx
    Java对接(BSC)币安链 | BNB与BEP20的开发实践(二)BNB转账、BEP20转账、链上交易监控
  • 原文地址:https://blog.csdn.net/sinat_17775997/article/details/126213348