MobX 上手指南,写 Vue 的感觉?

之前用 Redux 比较多,一直听说 Mobx 能让你体验到在 React 里面写 Vue 的感觉,今天打算尝试下 Mobx 是不是真的有写 Vue 的感觉。

题外话

在介绍 MobX 的用法之前,先说点题外话,我们可以看一下 MobX 的中文简介。在 MobX 的中文网站上写着:

MobX 是一个经过战火洗礼的库,它通过透明的函数响应式编程使得状态管理变得简单和可扩展。

数据流

“战火洗礼的库” 怎么看都感觉很奇怪,读起来很拗口????,而且网上很多介绍 MobX 的文章都是这么写的,在 github 翻阅其 README 发现写的是:

MobX is a battle tested library that makes state management simple and scalable by transparently applying functional reactive programming (TFRP).

可以看到作者原本要表达的意思是 MobX 是经过了许多的测试,拥有比较强的健壮性。下面是通过谷歌翻译的结果,看起来也比中文网的表达要准确一些。

谷歌翻译

虽然,我的英文水平也很菜,还是会尽量看官方的文档,这样可以避免一些不必要的误解。

如何使用?

言归正传,MobX 现在的最新版是 6.0,这个版本的 API 相比于之前有了极大的简化,可以说更加好用了。之前的版本是装饰器风格的语法糖,但是装饰器在现在的 ES 规范中并不成熟,而且引入装饰器语法也在增加打包后的代码体积。综合考虑后,MobX 6.0 取消了装饰器语法的 API。

响应式对象

MobX 通过 makeObservable 方法来构造响应式对象,传入的对象属性会通过  Proxy 代理,与 Vue 类似,在 6.0 版本之前使用的是   Object.defineProperty  API,当然 6.0 也提供了降级方案。

import { configure, makeObservable, observable, action, computed } from 'mobx'// 使用该配置,可以将 Proxy 降级为 Object.defineProperty
configure({ useProxies: "never" });// 构造响应对象
const store = makeObservable(// 需要代理的响应对象{count: 0,get double() {return this.count * 2},increment() {this.count += 1},decrement() {this.count -= 1}},// 对各个属性进行包装,用于标记该属性的作用{count: observable, // 需要跟踪的响应属性double: computed,  // 计算属性increment: action, // action 调用后,会修改响应对象decrement: action, // action 调用后,会修改响应对象}
)

我们在看看之前版本的 MobX,使用装饰器的写法:

class Store {@observable count = 0constructor() {makeObservable(this)}@action increment() {this.count++;}@action decrement() {this.count--;}@computed get double() {return this.count * 2}
}const store = new Store()

这么看起来,好像写法并没有得到什么简化,好像比写装饰器还要复杂点。下面我们看看 6.0 版本一个更强大的 API:makeAutoObservable

makeAutoObservable 是一个更强大的 makeObservable,可以自动为属性加上对象的包装函数,上手成本直线下降。

import { makeAutoObservable } from 'mobx'const store = makeAutoObservable({count: 0,get double() {return this.count * 2},increment() {this.count += 1},decrement() {this.count -= 1}
})

计算属性

MobX 的属性与 Vue 的 computed 一样,在 makeAutoObservable 中就是一个 gettergetter 依赖的值一旦发生变化,getter 本身的返回值也会跟随变化。

import { makeAutoObservable } from 'mobx'const store = makeAutoObservable({count: 0,get double() {return this.count * 2}
})

store.count 为 1 时,调用 store.double 会返回 2。

修改行为

当我们需要修改 store 上的响应属性时,我们可以通过直接重新赋值的方式修改,但是这样会得到 MobX 的警告⚠️。

const store = makeAutoObservable({count: 0
});document.getElementById("increment").onclick = function () {store.count += 1
}
warn

MobX 会提示,在修改响应式对象的属性时,需要通过 action 的方式修改。虽然直接修改也能生效,但是这样会让 MobX 状态的管理比较混乱,而且将状态修改放到 action 中,能够让 MobX 在内部的事务流程中进行修改,以免拿到的某个属性还处于中间态,最后计算的结果不够准确。

makeAutoObservable 中的所有方法都会被处理成 action。

import { makeAutoObservable } from 'mobx'const store = makeAutoObservable({count: 0,get double() {return this.count * 2},increment() { // actionthis.count += 1},decrement() { // actionthis.count -= 1}
})

不同于 Vuex,将状态的修改划分为 mutation 和 action,同步修改放到 mutation 中,异步的操作放到 action 中。在 MobX 中,不管是同步还是异步操作,都可以放到 action 中,只是异步操作在修改属性时,需要将赋值操作放到 runInAction 中。

import { runInAction, makeAutoObservable } from 'mobx'const store = makeAutoObservable({count: 0,async initCount() {// 模拟获取远程的数据const count = await new Promise((resolve) => {setTimeout(() => {resolve(10)}, 500)})// 获取数据后,将赋值操作放到 runInAction 中runInAction(() => {this.count = count})}
})store.initCount()

如果不调用 runInAction ,则可以直接调用本身已经存在的 action。

import { runInAction, makeAutoObservable } from 'mobx'const store = makeAutoObservable({count: 0,setCount(count) {this.count = count},async initCount() {// 模拟获取远程的数据const count = await new Promise((resolve) => {setTimeout(() => {resolve(10)}, 500)})// 获取数据后,调用已有的 actionthis.setCount(count)}
})store.initCount()

监听对象变更

无论是在 React 还是在小程序中想要引入 MobX,都需要在对象变更的时候,通知调用原生的 setState/setData 方法,将状态同步到视图上。

通过 autorun 方法可以实现这个能力,我们可以把 autorun 理解为 React Hooks 中的 useEffect。每当 store 的响应属性发生修改时,传入 autorun 的方法(effect)就会被调用一次。

import { autorun, makeAutoObservable } from 'mobx'const store = makeAutoObservable({count: 0,setCount(count) {this.count = count},increment() {this.count++},decrement() {this.count--}
})document.getElementById("increment").onclick = function () {store.count++
}const $count = document.getElementById("count")
$count.innerText = `${store.count}`
autorun(() => {$count.innerText = `${store.count}`
})

每当  button#increment 按钮被点击的时候,span#count 内的值就会自动进行同步。????查看完整代码。

效果演示

除了 autorun ,MobX 还提供了更精细化的监听方法:reactionwhen

const store = makeAutoObservable({count: 0,setCount(count) {this.count = count},increment() {this.count++},decrement() {this.count--}
})// store 发生修改立即调用 effect
autorun(() => {$count.innerText = `${store.count}`
});// 第一个方法的返回值修改后才会调用后面的 effect
reaction(// 表示 store.count 修改后才会调用() => store.count,// 第一个参数为当前值,第二个参数为修改前的值// 有点类似与 Vue 中的 watch(value, prevValue) => {console.log('diff', value - prevValue)}
);// 第一个方法的返回值为真,立即调用后面的 effect
when(() => store.count > 10, () => {console.log(store.count)
})
// when 方法还能返回一个 promise
(async function() {await when(() => store.count > 10)console.log('store.count > 10')
})()

总结

MobX 的介绍到这里就结束了,本文只是大致的列举了一下 MobX 的 API,希望大家能有所收获。后续打算再深入研究下 MobX 的实现,等我研究好了,再写篇文章来分享。


最近组建了一个江西人的前端交流群,如果你也是江西人可以加我微信ruochuan12 拉你进群。


常驻推荐阅读

若川知乎高赞:有哪些必看的 JS库?
我在阿里招前端,我该怎么帮你?(现在还可以加模拟面试群)
如何拿下阿里巴巴 P6 的前端 Offer
如何准备阿里P6/P7前端面试--项目经历准备篇
大厂面试官常问的亮点,该如何做出?
如何从初级到专家(P4-P7)打破成长瓶颈和有效突破
若川知乎问答:2年前端经验,做的项目没什么技术含量,怎么办?

常驻末尾

你好,我是若川,江西人~(点击蓝字了解我)历时一年只写了一个学习源码整体架构系列 有哪些必看的JS库:jQuery、underscore、lodash、sentry、vuex、axios、koa、redux

  1. 关注若川视野,回复"pdf" 领取优质前端书籍pdf,回复"1",可加群长期交流学习

  2. 我的博客地址:https://lxchuan12.gitee.io 欢迎收藏

  3. 觉得文章不错,可以 分享、点赞、在看 呀^_^另外欢迎留言交流~

小提醒:若川视野公众号面试、源码等文章合集在菜单栏中间【源码精选】按钮,欢迎点击阅读,也可以星标我的公众号,便于查找

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ansible中yaml语法应用

4、yaml语法应用 ansible的playbook编写是yaml语言编写,掌握yaml语法是编写playbook的必要条件,格式要求和Python相似,具体教程参考如下yaml语言教程 附上一个yaml文件转js格式文件链接在线免费yaml内容转json格式 4.1、 ansible中的yaml语法…

(送书和红包)快人一步,掌握前端函数式编程

大家好,我是若川。上周末送出了3本新书和若干红包,抽奖名单已公布。本周又争取到了4本《前端函数式编程》书籍包邮送给大家,抽奖规则见文末,与以往不同的是除了关键词、留言、在看抽奖外,还有最早关注奖,欢…

JavaScript操作表格进行拖拽排序

<js-dodo-table- Drag and Drop JQuery plugin>以上插件可对table进行排序&#xff0c;拖动&#xff01; 例如有下面一个样子的id为table的表格&#xff1a; <table id"table"cellspacing"0"cellpadding"2"><tr id"1"…

ping -a 获取不到主机名_网络测试命令——PING

命令功能&#xff1a;Linux系统和windows系统的ping命令是常用的网络命令&#xff0c;它通常用来测试与目标主机的连通性&#xff0c;这样我们就可以根据它ping输出的信息来确定目标主机是否可访问(但这不是绝对的)。有些服务器为了防止通过ping探测到&#xff0c;通过防火墙设…

写在2021: 值得关注/学习的前端框架和工具库

前言最近在知乎看到了这么个问题&#xff1a;学完Vue还有必要学习React和Node吗&#xff1f;[1]&#xff0c; 有很奇妙的感觉&#xff0c;因为我在最开始入门前端时&#xff0c;也是以Vue入的门&#xff0c;在“学完”Vue之后&#xff0c; 我也有了这个疑问&#xff0c;但当时的…

万物互联之~RPC专栏

3.RPC引入 上篇回顾&#xff1a;万物互联之~深入篇 Code&#xff1a;https://github.com/lotapp/BaseCode/tree/master/python/6.net/6.rpc/ 其他专栏最新篇&#xff1a;协程加强之~兼容答疑篇 | 聊聊数据库~SQL环境篇 3.1.概念 RPC(Remote Procedure Call)&#xff1a;分布式系…

前端进阶必备Node.js,你得了解一下

作为前端开发&#xff0c;工作中肯定离不开 JavaScript &#xff0c;而 Node.js 是基于 JavaScript 语言和 V8 引擎的 Web 服务器项目&#xff0c;让你可以直接使用 JavaScript 来搭架服务器。而且在 Node 环境下&#xff0c;通过模块化的 JavaScript 代码&#xff0c;加上函数…

Web Components 上手指南

现在的前端开发基本离不开 React、Vue 这两个框架的支撑&#xff0c;而这两个框架下面又衍生出了许多的自定义组件库&#xff1a;Element&#xff08;Vue&#xff09;Ant Design&#xff08;React&#xff09;这些组件库的出现&#xff0c;让我们可以直接使用已经封装好的组件&…

如何远程连接Windows和linux服务器

linux的方法在下面 Windows服务器远程连接 登录控制台查看服务器系统是什么系统例如阿里云的ECS服务器 Windows系统可以使用微软自带的远程工具进行连接&#xff0c;可以连接的系统有Windows server 和Windows 7-10 等等系列&#xff1b;Windows系统&#xff0c;例如Windows10系…

手把手教你接入前端热门抓包神器 - whistle

大家好&#xff0c;我是若川&#xff0c;今天推荐腾讯前端团队的这篇好文。whistle 是一个基于 Node.js 的跨平台网络调试工具。最近随着 Nohost 的开源&#xff0c;有不少同学问了 whistle 相关的问题&#xff0c;本篇文章将结合几个常见的业务场景介绍如何在本地前端项目开发…

React 与 Vue 框架的设计思路大 PK

大家好&#xff0c;我是若川。今天分享一篇框架设计思路的好文。关于我 大家好我是花果山的大圣&#xff0c;今天很荣幸&#xff0c;有机会跟大家分享一下很多年轻人感兴趣的话题《 Vue 和 React 设计思想 PK》,个人水平有限&#xff0c;如果有理解不到位的请倾盆&#xff0c;大…

php foreach id是否存在数组_请纠正这 5 个 PHP 编码小陋习

在做过大量的代码审查后&#xff0c;我经常看到一些重复的错误&#xff0c;以下是纠正这些错误的方法。在循环之前测试数组是否为空$items [];// ...if (count($items) > 0) {foreach ($items as $item) {// process on $item ...}}foreach以及数组函数 (array_*) 可以处理…

1161转进制(C语言)

一&#xff1a;题目 二&#xff1a;思路分析 1.首先该题目让我们使用递归求十进制转其他进制 2.其次&#xff0c;我们要知道十进制转换为其他进制怎么转换&#xff0c;以例题所给的数据为例 由此图可以看出&#xff0c;十进制转换为其他进制&#xff0c;是辗转相除法&#xf…

应对无协议脱欧 葡萄牙机场将为英籍旅客设快速通道

中新网1月18日电 据台湾《联合报》援引英媒报道&#xff0c;英国首相特蕾莎•梅的脱欧协议遭下院否决后&#xff0c;英国无协议脱欧的可能性变大。葡萄牙总理科斯塔17日表示&#xff0c;里斯本当局正对机场开设特殊通道进行规划&#xff0c;使英国旅客无论英国最后如何脱欧&…

6轮字节前端校招面试经验分享

大家好&#xff0c;我是若川。最近金三银四&#xff0c;今天分享一篇字节前端校招面试经验的轻松好文&#xff0c;相信看完会有所收获。也欢迎点击下方卡片关注或者星标我的公众号若川视野因为我错过了2020年的秋招&#xff08;ps: 那时候连数据结构与算法都还没学完&#xff0…

斥资近1亿港元,小米二次回购

1月21日消息&#xff0c;小米集团发布公告称&#xff0c;公司于1月18日回购了984.96万股B类普通股股票&#xff0c;占已发行股份0.041%&#xff0c;平均价为每股B类股10.1527港元&#xff0c;总计斥资近1亿港元。 这也是继1月17日首次回购后&#xff0c;小米集团连续两日出手进…

ios macos_设计师可以从iOS 14和macOS Big Sur中学到什么?

ios macos重点 (Top highlight)With the introduction of iOS 14 and macOS Big Sur, we are the witness of the next big thing in UI Design. Changes are not so revolutionary like in iOS 7 years before, but they undoubtedly present the trend UI Designers will fol…

网页设计简约_简约网页设计的主要功能

网页设计简约重点 (Top highlight)Minimalism is synonymous with simplicity. Not quite. As the name suggests, minimalism is definitely not about opulent design. But the assumption that minimalism is design-less and plain is also wrong. Minimalism is simple ye…

Expo 2010 Japan Pavilion

^_^转载于:https://www.cnblogs.com/mmmhhhlll/archive/2010/04/16/1713680.html

深度对比学习Vue和React两大框架

作为国内应用最广的两个框架&#xff0c;Vue 和 React 是前端必须掌握的内容&#xff0c;也是面试的重点。但大多数读者都只擅长其中一个框架&#xff0c;当面试涉及到另一个框架的内容时&#xff0c;就答不好了。比如虚拟dom&#xff0c;两个框架中都有应用&#xff0c;面试官…