结合 Vue.observable 写一个简易 Vuex
作为 Vue 全家桶的一员,Vuex 的重要性不言而喻,不管是用来管理状态,还是封装 Controler 都很好用
不过在一些体量较小的项目中,为了几个简单的状态或者处理函数而引入 Vuex,就像是高射炮打蚊子,大材小用了
这时候就可以模拟 Vuex,自己写一个简单的 Store, 用来管理状态并实时更新数据
一、构造函数
模拟 Vuex 的结构,创建一个 Class
export default class Store {
  constructor({ states, actions, mutations }) {
    // 状态
    this.states = states || {};
    // 异步函数
    this.actions = actions || {};
    // 同步函数
    this.mutations = mutations || {};
  }
  // 调用 mutations 中的同步函数
  commit = (fun, params) => {};
  // 调用 actions 中的异步函数
  dispatch = (fun, params) => {};
  // 更新 states 的状态
  update = (key, value) => {};
}
然后实例化一个 Store
import Store from './store'; import states from './states';
import actions from './actions';
import mutations from './mutations'; const store = new Store({
states,
actions,
mutations,
}); export default store;
然后挂到 vue 的原型上,通过 vue.$store 的方式使用,一个高仿 vuex 的架子就搭好了
// 在 main.js 中引入 Store
import store from './store/index';
Vue.prototype.$store = store;
二、实现操作函数(commit、dispatch、update)
在 Vuex 中,如果需要更新 state 中的状态,需要通过 commit 调用 mutations 中的方法
而 mutations 的方法都具备一个默认的参数 state,因此 commit 方法可以这么写:
// 向 mutations 中的传入固定参数 state
commit = (fun, params) => {
this.mutations[fun](this.states, params);
};
不过由于一些历史遗留问题,我习惯用 this.states 的方式获取 state(这个习惯不好),所以改成了这样:
  commit = (fun, params) => {
    if (fun) {
      this.mutations[fun].call(this, params);
    } else {
      return false;
    }
  };
类似的 actions 和 update 可以参考 commit 的写法
三、响应式对象
目前的 store 有一个致命的问题:state 更新之后并不会即时渲染到视图层
这时候 Vue 2.6.0 新增的 observable() 就派上用场了
如果将一个对象作为入参传给 Vue.observable() ,经过处理之后,这个对象在 Vue 内就可以实时更新
其返回值可以直接用于 render 和 computed 中,并且会在发生改变时触发相应的更新
于是 Store 的构造函数需要改一改:
  constructor({ states, actions, mutations }) {
    // 状态
    this.states = Vue.observable(states || {});
    // 异步函数
    this.actions = Vue.observable(actions || {});
    // 同步函数
    this.mutations = Vue.observable(mutations || {});
  }
⚠️注意:
假如对象 obj 经过 observable() 处理之后,赋值给了新对象 new_obj
在 Vue 2.x 中,直接修改 obj 也会触发 new_obj 的更新
但在 Vue 3.x 中,由于响应机制的变更,只有修改 new_obj 才能触发视图层的更新
所以在使用 observable() 的时候,最好始终操作使用 observable() 处理后的 new_obj
四、简单用用
超低配的 Vuex 已经写好了,上面已经把 store 挂到 Vue 的原型上,所以可以直接使用
假如 state 中已经存在一个状态 name,在组件中可以通过 computed 去获取
computed: {
    name() {
      return this.$store.states.name;
    },
}
如果需要修改状态,可以通过 $store.update()
methods: {
    updateName(val) {
        this.$store.update('name', val);
    }
}
或者使用 $store.commit() 调用 mutations 中的方法
methods: {
    commitName(val) {
        this.$store.commit('handleNameChange', val);
    }
}
大功告成~
结合 Vue.observable 写一个简易 Vuex的更多相关文章
- Summer——从头开始写一个简易的Spring框架
		
Summer--从头开始写一个简易的Spring框架  参考Spring框架实现一个简易类似的Java框架.计划陆续实现IOC.AOP.以及数据访问模块和事务控制模块. ...
 - 手写一个简易的IOC
		
这个小项目是我读过一点Spring的源码后,模仿Spring的IOC写的一个简易的IOC,当然Spring的在天上,我写的在马里亚纳海沟,哈哈 感兴趣的小伙伴可以去我的github拉取代码看着玩 地址 ...
 - 来,我们手写一个简易版的mock.js吧(模拟fetch && Ajax请求)
		
预期的mock的使用方式 首先我们从使用的角度出发,思考编码过程 M1. 通过配置文件配置url和response M2. 自动检测环境为开发环境时启动Mock.js M3. mock代码能直接覆盖g ...
 - 如何用 Python 写一个简易的抽奖程序
		
不知道有多少人是被这个头图骗进来的:) 事情的起因是这样的,上周有同学问小编,看着小编的示例代码敲代码,感觉自己也会写了,如果不看的话,七七八八可能也写的出来,但是一旦自己独立写一段程序,感觉到无从下 ...
 - 手写一个简易的多周期 MIPS  CPU
		
一点前言 多周期 CPU 相比单周期 CPU 以及流水线 CPU 实现来说其实写起来要麻烦那么一些,但是相对于流水线 CPU 和单周期 CPU 而言,多周期 CPU 除了能提升主频之外似乎并没有什么卵 ...
 - 写一个简易web服务器、ASP.NET核心知识(4)
		
前言 昨天尝试了,基于对http协议的探究,我们用控制台写了一个简单的浏览器.尽管浏览器很low,但是对于http协议有个更好的理解. 说了上面这一段,诸位猜到我要干嘛了吗?(其实不用猜哈,标题里都有 ...
 - 写一个简易浏览器、ASP.NET核心知识(3)
		
前言 先在文章前面说好了,省得大家发现我根本没有这样的头发,duang的一下一堆人骂我. 这篇文章的标题有点大,其实挺low的,我需要在开头解释一下.我这里只想写一个小的控制台,旨在模拟浏览器的htt ...
 - Vue.js写一个SPA登录页面的过程
		
技术栈 vue.js 主框架 vuex 状态管理 vue-router 路由管理 一般过程 在一般的登录过程中,一种前端方案是: 检查状态:进入页面时或者路由变化时检查是否有登录状态(保存在cooki ...
 - 用python 10min手写一个简易的实时内存监控系统
		
简易的内存监控系统 本文需要有一定的python和前端基础,如果没基础的,请关注我后续的基础教程系列博客 文章github源地址,还可以看到具体的代码,喜欢请在原链接右上角加个star 腾讯视频链接 ...
 
随机推荐
- SLAM:
			
十四讲: 传感器约束了外部环境 测到的通常都是一些间接的物理量而不是直接的位置数据 只能通过一些间接的手段,从这些数据推算自己的位置 好处是没有对环境提出任何要求 camera:单目.双目.深度 Mo ...
 - JDOJ 1770 埃及分数
			
JDOJ 1770: 埃及分数 https://neooj.com/oldoj/problem.php?id=1770 Description 分子均为1的分数叫做埃及分数,因为古代埃及人在进行分数运 ...
 - 了解html
			
什么是html? html:Hyper Text Markup Language(超文本标记语言) 纯文本:只能存储一些简单的字符(不能插入图片.视频...) 注意:html不是一种编程语言(它没有任 ...
 - vue-loader和单页组件介绍
			
一.Vue Loader介绍 Vue Loader 是一个 webpack 的loader,它允许你以一种名为 单文件组件(SFCs)的格式撰写 Vue 组件.官方文档地址如下所示: Vue Load ...
 - MySQL实战45讲学习笔记:第十讲
			
一 .本节内容概要 前面我们介绍过索引,你已经知道了在 MySQL 中一张表其实是可以支持多个索引的.但是,你写 SQL 语句的时候,并没有主动指定使用哪个索引.也就是说,使用哪个索引是由MySQL ...
 - MySQL实战45讲学习笔记:第二十四讲
			
一.引子 在前面的文章中,我不止一次地和你提到了 binlog,大家知道 binlog 可以用来归档,也可以用来做主备同步,但它的内容是什么样的呢?为什么备库执行了 binlog 就可以跟主库保持一致 ...
 - [LeetCode] 395. Longest Substring with At Least K Repeating Characters 至少有K个重复字符的最长子字符串
			
Find the length of the longest substring T of a given string (consists of lowercase letters only) su ...
 - Export failed for github.com/hashicorp/consul: Unable to export source: exit status 128
			
背景 go项目,使用glide install命令去下载安装依赖,依赖中有个github.com/hashicorp/consul 问题描述 一直无法下载安装依赖成功,报错如下: [ERROR] Ex ...
 - sql server 索引优化
			
查询实际执行计划,看走的是那种查询 要根据需求,建立合适的索引 经常需要汇总的,可以建立包含索引 --drop index ix_smssend_created on smssent_1 ; crea ...
 - 【C/C++开发】C++静态库与动态库以及在Linux和Windows上的创建使用
			
原文出处: 吴秦的博客 这次分享的宗旨是--让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学 ...