比较
原生语法
小程序原生语法是开发者所能接触到的最底层,这也是写小程序的唯一方法,任何其他方案最终都要通过原生语法才能工作。小程序刚诞生时原生语法可能还不算太糟糕,但如今 TS 越来越受欢迎,而原生语法对 TS 的支持却很羸弱。并且 React Hooks 横空出世,彻底改变了 UI 逻辑的编写方式,Vue 也根据自己的响应式数据提出了 Composition API,有着与 React Hooks 相同的能力。在这种背景下原生语法已经很难让人满意,Vue Mini 通过将 Vue 的 Composition API 引入小程序,从而解决了这些问题。Vue Mini 与原生语法也并不是二选一的关系,它们可以很好的协同工作。
Taro 2 / Rax 编译时
Taro 2 是个很有想象力的方案(Rax 编译时与 Taro 2 基本类似),你可以像写 React 一样写小程序,它通过编译时的静态分析将你的类 React 组件还原成原生语法。可是这其中有个致命的问题,React Render Function / JSX 是极其动态的,而原生语法的 Template 是比较静态的。都知道把静态模版编译为动态渲染函数不难,反过来却难如登天。也就是这个根本原因导致 Taro 2 有很多难以解决的问题,Taro 团队可能也意识到这条路是个死胡同,所以 Taro 3 抛弃了编译时方案。而 Vue Mini 目前只是一个轻量的纯运行时库,它并不依赖任何编译时手段。
Taro 3 / Remax / kbone / Rax 运行时
Taro 3 / Remax / kbone / Rax 运行时,这四个方案的实现细节略有不同,但可以大致归为同一类。Taro 3 / kbone / Rax 运行时,这三个方案是通过模拟实现 DOM API 来让现有的 Web 框架可以跑在小程序上,最终通过模拟的 DOM API 生成 VDOM,而 Remax 是实现了一个自定义的 react-reconciler 直接承接 React 生成的 VDOM。最终它们都是将 VDOM 作为小程序组件的 data 发送给模版,然后通过模版语法在运行时暴力递归 VDOM 生成最终的 UI 树。可以了解到这类方案是重运行时的,很暴力,但有效。可是这类方案也是带着原罪出生的,主要问题有两个:一个是这类方案都带有一个很大的运行时,一个 Hello World 小程序,Taro 3 的大小是 280KB,Remax 更是达到了 305KB,而作为对比 Vue Mini 只有 26KB,虽然这样的对比并不严谨,但大致也可以说明问题。另一个问题是这类方案有很大的性能开销,页面稍微复杂一点卡顿几乎无法避免,而 Vue Mini 完全依赖小程序自己的运行时,只是在响应式数据变化时点对点的更新小程序组件的 data,因此 Vue Mini 有着与原生小程序十分接近的性能表现。详情请查看 Benchmark。
Mpx
Mpx 的设计哲学与 Vue Mini 十分相似,二者都是以小程序为基准走增强路线。它们最显著的区别可能是 Mpx 是基于 Vue 2 的,而 Vue Mini 是基于 Vue 3 的。
uni-app
uni-app 与 Vue Mini 的区别主要在两个方面,一是实现方案不同,二是设计哲学不同。uni-app 会在每个小程序组件实例初始化时创建一个对应的 Vue 组件实例,uni-app 会在小程序组件与 Vue 组件之间做同步,开发者的代码运行在 Vue 组件上。小程序组件的 Properties 变化了就同步给 Vue 组件,小程序组件的生命周期被触发了就去调用 Vue 组件的生命周期。反过来开发者声明的响应式数据变化了会经由 Vue 组件同步给小程序组件。Vue Mini 并没有这样的影子组件,Vue Mini 就是直接将响应式数据同步给小程序组件,方法与生命周期也都是直接添加到小程序组件上。事实上 Vue Mini 根本没有 Vue 组件的概念,只有小程序组件。相比而言,Vue Mini 的设计更简洁,抽象更少,自然也更不容易出错。而且 Vue Mini 的体积更小,内存占用更少,理论上速度也更快。另外 uni-app 与 Vue Mini 的设计哲学也不同。uni-app 是尽可能靠近 Vue,努力将 Vue 渲染到小程序,我甚至觉得 uni-app 有在试图隐藏小程序的概念,尽量不让开发者感知到他们在写小程序。而 Vue Mini 是在原生小程序基础上借助 Vue 做增强,更靠近小程序,开发者会非常清晰的感知到他们是在写小程序,而且需要对小程序有一定的了解。Vue Mini 这样的设计选择是经过深思熟虑的,因为这样可以减少各种各样的坑,并且能更好更无痛的使用小程序本身的各种 API。