基于 MobX 构建视图框架无关的数据层-与 Vue 的结合

(点击上方公众号,可快速关注)


来源:kuitos

github.com/kuitos/kuitos.github.io/issues/39


mobx-vue 目前已进入 mobxjs 官方组织

几周前我写了一篇文章描述了 mobx 与 angularjs 结合使用的方式及目的 (老树发新芽—使用 mobx 加速你的 AngularJS 应用),这次介绍一下如何将 MobX 跟 Vue 结合起来。

安装
npm i mobx-vue -S
使用

mobx-vue 的使用非常简单,只需要使用 connect 将你用 mobx 定义的 store 跟 vue component 连接起来即可:

<template>
   
<section>
       
<p v-text="amount"></p>
       
<p v-for="user in users" :key="user.name">{{user.name}}</p>
   
</section>
</template>
<script lang="ts">
   
import { Connect } from "mobx-vue";
   
import Vue from "vue";
   
import Component from "vue-class-component";
   
class ViewModel {
       
@observable users = [];
       
@computed get amount() { return this.users.length }
       
@action fetchUsers() {}
   
}
   
@Connect(new ViewModel())
   
@Component()
   
export default class App extends Vue {
       mounted
() {
           
this.fetchUsers();
       
}
   
}
</script>
Why MobX/mobx-vue

我们知道,mobx 跟 vue 都是基于 数据劫持&依赖收集 的方式来实现响应式机制的。mobx 官方也多次提到 inspired by vue,那么我们为什么还要将两个几乎一样的东西结合起来呢?

Yes, it’s weird.

2016年我在构建公司级组件库的时候开始思考一个问题,我们如何在代码库基于某一框架的情况下,能以尽可能小的代价在未来将组件库迁移到其他 框架/库 下?总不能基于新的技术全部重写一遍吧,这也太浪费生命了。且不说对于基础控件而言,交互/行为 逻辑基本上是可确定的,最多也就是 UI 上的一些调整,而且单纯为了尝试新技术耗费公司人力物力将基础库推导重写也是非常不职业的做法。那么我们只能接受被框架绑架而只能深陷某一技术栈从此泥潭深陷吗?对于前端这种框架半衰期尤其短的领域而言显然是不可接受的,结果无非就是要么自己跑路坑后来人,要么招不到人来一起填坑… 简单来说我们无法享受新技术带来的种种红利。

在 MVVM 架构视角下,越是重型的应用其复杂度越是集中在 M(Model) 跟 VM(ViewModel) 这两层,尤其是 Model 层,理论上应该是能脱离上层视图独立运行独立发布独立测试的存在。而相应的不同视图框架只是使用了不同绑定语法的动态模板引擎而已,这个观点我在前面的几篇文章里都讲述过。所以只要我们将视图层做的很薄,我们迁移的成本自然会降到一个可接受的范畴,甚至有可能通过工具在编译期自动生成不同框架的视图层代码。

要做到 Model 甚至 ViewModel 独立可复用,我们需要的是一种可以帮助我们描述各数据模型间依赖关系图且框架中立的通用状态管理方案。这期间我尝试过 ES6 accessor、redux、rxjs 等方案,但都不尽如人意。accessor 过于底层且异步不友好、redux 开发体验太差(参考Redux数据流管理架构有什么致命缺陷,未来会如何改进?)、rxjs 过重等等。直到后来看到 MobX:MobX 语法足够简单、弱主张(unopinioned)、oop 向、框架中立等特性正好符合我的需求。

在过去的一年多里,我分别在 react、angularjs、angular 上尝试过基于 MobX 构建 VM/M 层,其中有两个上线项目,一个个人项目,实践效果基本上也达到了我的预期。在架构上,我们只需要使用对应的 connector,就能基于同一数据层,在不同框架下自如的切换。这样看来,这套思路现在就剩 Vue 没有被验证了。

在 mobx-vue 之前,社区已经有一些优秀的 connector 实现,如 movuevue-modex 等,但基本都是基于 vue 的插件机制且 inspired by vue-rx,除了使用起来相对繁琐的问题外,最大的问题是其实现基本都是借助 Vue.util.defineReactive 来做的,也就是说还是基于 Vue 自有的响应式机制,这在一定程度不仅浪费了 MobX 的reactive 能力,而且会为迁移到其他视图框架下埋下了不确定的种子(毕竟你无法确保是 Vue 还是 MobX 在响应状态变化)。

参考:why mobx-vue(https://github.com/mobxjs/mobx-vue#why-mobx-vue)

理想状态下应该是由 mobx 管理数据的依赖关系,vue 针对 mobx 的响应做出 re render 动作即可,vue 只是一个单纯的动态模板渲染引擎,就像 react 一样。

在这样的一个背景下,mobx-vue 诞生了。

mobx-vue 是如何运作的

既然我们的目的是将 vue 变成一个单纯的模板渲染引擎(vdom),并且使用 mobx 响应式机制取代 vue 的响应式,那么只要我们劫持到 Vue 的组件装载及更新方法,然后在组件装载的时候收集依赖,在依赖发生变更时更新组件即可。

以下内容与其叫做 mobx-vue 是如何运作的,不如叫 Vue 源码解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值