有时候,我挺羡慕 React 的生态。 React Native、Expo、Next.js,哪哪都有它的影子。 但我自己是个 Vue 党。写惯了 v-if
、v-for
,再去写 useEffect
,总觉得像拿筷子吃汉堡。
我在 GitHub 上看到一个库------nativescript-vue
。 一句话介绍:用 Vue 写原生 iOS/Android 应用。 当时我心里就一激灵------这不就是我梦寐以求的开发体验吗?

于是,我花了一个周末,认真玩了一遍。结果,真香。
一、这玩意到底是干嘛的?
如果你用过 Vue,你知道它是前端三件套里的"灵魂"。 模板、组件、响应式数据流------这些在浏览器里都挺熟悉。
但 nativescript-vue
做了一件有点"叛逆"的事: 它不要浏览器。
你写的 <Button>
、<Label>
、<StackLayout>
不是 DOM 元素, 而是真实的原生控件。 在 iOS 上是 UIButton
、UILabel
,在 Android 上是 android.widget.Button
、TextView
。 这些控件是系统级的,能直接访问相机、GPS、文件系统、蓝牙。
换句话说,它不是像 Capacitor 或 WebView 那样"套壳", 而是真·原生应用。
当我第一次在 iPhone 模拟器上看到自己写的 Vue 组件变成了原生界面时, 那种感觉挺奇妙的: "原来我写的 Vue,也能跑在没有浏览器的世界。"
二、上手其实挺快的
官方的示例写得挺"家常":
js
<template>
<Page>
<ActionBar title="Hello Vue" />
<StackLayout>
<Label :text="message" />
<Button text="点击我" @tap="onTap" />
</StackLayout>
</Page>
</template>
<script>
export default {
data: () => ({ message: 'Hello NativeScript-Vue!' }),
methods: {
onTap() { this.message = '你点了一下按钮!' }
}
}
</script>
我第一次跑起来的时候, 点击按钮、文本变了。 很熟悉的 Vue 写法,但屏幕上出现的却是原生动画、原生字体。 完全不像 WebView 那种"假装自己是原生"的感觉。
三、它是怎么做到的?
这个部分稍微 geek 一点,但挺有意思。
Vue 本身有个"渲染器(renderer)"概念。 正常我们在 Web 里写 Vue,它的 renderer 会把虚拟 DOM 变成 HTML 元素。 而 nativescript-vue
做的事是: 自定义渲染器,把虚拟节点映射到 NativeScript 的原生控件上。
比如 <Label>
对应的是 new Label()
(NativeScript 提供的原生对象), @tap
对应绑定原生的点击事件, style
对应设置原生属性(比如字体、颜色、布局参数)。
Vue 的响应式系统不变, 只是渲染目标从 "DOM" 换成了 "Native"。
这其实很像一个"翻译机": Vue 负责生成虚拟节点树, NativeScript 负责把它翻译成 iOS/Android 能理解的控件树。
这就是为什么你能写 Vue 语法,却得到原生 App 的原因。
四、它和 React Native 有啥区别?
说实话,概念上几乎一模一样。
React Native:React + 自定义渲染器 → 原生控件 NativeScript-Vue:Vue + 自定义渲染器 → 原生控件
不同的只是哲学。 React Native 更工程化,模块化程度高,但上手曲线也陡一点。 Vue 的世界则更温柔------模板、数据、方法都摆在眼前。
我觉得最大的不同在"写代码的心态"。 在 Vue 里,我更倾向于写"描述", 在 React 里,我得写"逻辑"。 这两种思维差别,放到原生开发上,体验就完全不同。
五、能干啥?能用吗?
别被"实验性"这个词吓到。 nativescript-vue
已经在多个实际项目里被用来做:
- 原生 UI 应用(资讯、社交、表单类)
- IOT 类 App(用原生 API 访问蓝牙、传感器)
- 小团队快速开发 MVP 原型
NativeScript 本身的生态挺全的, 地图、推送、扫码、摄像头、网络请求都有官方或第三方插件。 最酷的是: 你能直接用 JavaScript 调 iOS/Android 的原生 API。 真·直接调用,不是那种"通过桥接层再转一圈"的。
比如:
js
import { android } from '@nativescript/core/platform';
console.log(android.os.Build.VERSION);
这句会直接打印出 Android 系统版本。 当我第一次看到这行代码能跑,我真的愣了一下。 ------这已经不是 Web 了,这是原生。
六、但,也有坑
别以为能跑起来就是完事。 nativescript-vue
也有自己的坑。
首先,布局系统不是 CSS。 虽然你可以写类似的语法,但底层是原生布局模型(StackLayout
、GridLayout
)。 写法要换个脑子。
其次,生态确实不如 React Native 热闹。 很多问题得自己看源码。 有时候你会被一个小 bug 卡住半天,然后发现------ 官方 issue 里最后一个回复还是三个月前。
但,这也是它的魅力。 它不像 React Native 那么重, 你能直接看到渲染链路,能摸到框架的边界。 对于一个想了解"Vue 底层渲染机制"的人来说, 这简直是天然的实验田。
七、我学到的,不只是一个框架
玩完 NativeScript-Vue,我最大的收获不是"又多了一个跨端框架"。 而是------我终于理解了 Vue 是怎么"渲染"的。
以前我总觉得 Vue 就是个黑盒: 写模板 → magic → 页面更新。 但看过 NativeScript-Vue 的实现后,我明白了: Vue 自身只是生成一棵"虚拟节点树", 真正决定渲染结果的,是"renderer"。
于是我突然意识到, Vue 其实是个通用的 UI 框架,它并不依赖于浏览器。 你甚至可以让它渲染到命令行、Canvas、3D 世界、甚至机器人界面上。
NativeScript-Vue 只是其中一个"渲染目标"而已。
八、最后
如果你也是个 Vue 开发者, 又一直想写原生 App, 我建议你抽个周末玩一下 NativeScript-Vue。
你会发现: 自己写的那一套 Vue 组件, 居然能在 iPhone 上流畅地滑动、点击、弹出动画。 那一刻,会有点小感动。
这玩意不完美, 但它够"真"。 不浮夸,不虚拟,不 webview。 是你熟悉的 Vue,是手机真正的控件。
而这种"熟悉的陌生感", 正是技术最迷人的地方。
如果你看到这里, 不妨想一想: 是不是很多我们以为"只能在浏览器里做的事", 其实,只是没人告诉你可以用另一种方式去实现而已。