大家好,我是鱼樱!!!
关注公众号【鱼樱AI实验室】
持续分享更多前端和AI辅助前端编码新知识~~
不定时写点笔记写点生活~写点前端经验。
在当前环境下,纯前端开发者可以通过技术深化、横向扩展、切入新兴领域以及产品化思维找到突破口。
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
前端最卷的开发语言一点不为过,三天一小更,五天一大更。。。一年一个框架升级~=嗯,要的就是这样感觉!与时俱进~ 接下来会逐步分享uni-app
的一些开发经验。从文档到基础到实战以及遇到的问题~时间节点不限。
uni-app组成和跨端原理
uni-app
约定了如下开发规范
- 页面文件遵循 Vue 单文件组件 (SFC) 规范,即每个页面是一个.vue文件
- 组件标签靠近小程序规范,详见uni-app 组件规范
- 接口能力(JS API)靠近小程序规范,但需将前缀
wx
、my
等替换为uni
,详见uni-app接口规范 - 数据绑定及事件处理同
Vue.js
规范,同时补充了应用生命周期及页面的生命周期 - 如需兼容app-nvue平台,建议使用flex布局进行开发
uni-app分编译器
和运行时(runtime)
。uni-app能实现一套代码、多端运行,是通过这2部分配合完成的。
编译器将开发者的代码进行编译,编译的输出物由各个终端的runtime进行解析,每个平台(Web、Android App、iOS App、各家小程序)都有各自的runtime。
编译器
-
编译器运行在电脑开发环境。一般是内置在HBuilderX工具中,也可以使用独立的cli版。
-
开发者按uni-app规范编写代码,由编译器将开发者的代码编译生成每个平台支持的特有代码
-
在web平台,将.vue文件编译为js代码。与普通的vue cli项目类似
-
在微信小程序平台,编译器将.vue文件拆分生成wxml、wxss、js等代码
-
在app平台,将.vue文件编译为js代码。进一步,如果涉及uts代码:
- 在Android平台,将.uts文件编译为kotlin代码
- 在iOS平台,将.uts文件编译为swift代码
-
-
编译器分vue2版和vue3版
- vue2版:基于
webpack
实现 - vue3版:基于
Vite
实现,性能更快 (注意:uni-app x
中只支持 Vue3)
- vue2版:基于
-
编译器支持条件编译,即可以指定某部分代码只编译到特定的终端平台。从而将公用和个性化融合在一个工程中。
js
// #ifdef App
console.log("这段代码只有在App平台才会被编译进去。非App平台编译后没有这段代码")
// #endif
逻辑层和渲染层分离
在web平台,逻辑层(js)和渲染层(html、css),都运行在统一的webview里。
但在小程序和app端,逻辑层和渲染层被分离了。
分离的核心原因是性能。过去很多开发者吐槽基于webview的app性能不佳,很大原因是js运算和界面渲染抢资源导致的卡顿。
不管小程序还是app,逻辑层都独立为了单独的js引擎,渲染层仍然是webview(app上也支持纯原生渲染)。
所以注意小程序和app的逻辑层都不支持浏览器专用的window、dom等API。app只能在渲染层操作window、dom,即renderjs。
页面差异
uni-app项目中,一个页面就是一个符合Vue SFC规范
的 vue 文件。
-
在 uni-app js 引擎版中,后缀名是
.vue
文件或.nvue
文件。 这些页面均全平台支持,差异在于当 uni-app 发行到App平台时,.vue
文件会使用webview进行渲染,.nvue
会使用原生进行渲染,详见:nvue原生渲染。一个页面可以同时存在vue和nvue,在pages.json的路由注册中不包含页面文件名后缀,同一个页面可以对应2个文件名。重名时优先级如下:
- 在非app平台,先使用vue,忽略nvue
- 在app平台,使用nvue,忽略vue
-
在 uni-app x 中,后缀名是
.uvue
文件uni-app x 中没有js引擎和webview,不支持和vue页面并存。
uni-app x 在app-android上,每个页面都是一个全屏activity,不支持透明。
nvue 开发与 vue 开发的常见区别(官方原话)
- nvue 页面控制显隐只可以使用
v-if
不可以使用v-show
- nvue 页面只能使用
flex
布局,不支持其他布局方式。页面开发前,首先想清楚这个页面的纵向内容有什么,哪些是要滚动的,然后每个纵向内容的横轴排布有什么,按 flex 布局设计好界面。 - nvue 页面的布局排列方向默认为竖排(
column
),如需改变布局方向,可以在manifest.json
->app-plus
->nvue
->flex-direction
节点下修改,仅在 uni-app 模式下生效。详情。 - nvue 页面编译为 H5、小程序时,会做一件 css 默认值对齐的工作。因为 weex 渲染引擎只支持 flex,并且默认 flex 方向是垂直。而 H5 和小程序端,使用 web 渲染,默认不是 flex,并且设置
display:flex
后,它的 flex 方向默认是水平而不是垂直的。所以 nvue 编译为 H5、小程序时,会自动把页面默认布局设为 flex、方向为垂直。当然开发者手动设置后会覆盖默认设置。 - 文字内容,必须、只能在
<text>
组件下。不能在<div>
、<view>
的text
区域里直接写文字。否则即使渲染了,也无法绑定 js 里的变量。 - 只有
text
标签可以设置字体大小,字体颜色。 - 布局不能使用百分比、没有媒体查询。
- nvue 切换横竖屏时可能导致样式出现问题,建议有 nvue 的页面锁定手机方向。
- 支持的 css 有限,不过并不影响布局出你需要的界面,
flex
还是非常强大的。详见 - 不支持背景图。但可以使用
image
组件和层级来实现类似 web 中的背景效果。因为原生开发本身也没有 web 这种背景图概念 - css 选择器支持的比较少,只能使用 class 选择器。详见
- nvue 的各组件在安卓端默认是透明的,如果不设置
background-color
,可能会导致出现重影的问题。 class
进行绑定时只支持数组语法。- Android 端在一个页面内使用大量圆角边框会造成性能问题,尤其是多个角的样式还不一样的话更耗费性能。应避免这类使用。
- nvue 页面没有
bounce
回弹效果,只有几个列表组件有bounce
效果,包括list
、recycle-list
、waterfall
。 - 原生开发没有页面滚动的概念,页面内容高过屏幕高度并不会自动滚动,只有部分组件可滚动(
list
、waterfall
、scroll-view/scroller
),要滚得内容需要套在可滚动组件下。这不符合前端开发的习惯,所以在 nvue 编译为 uni-app 模式时,给页面外层自动套了一个scroller
,页面内容过高会自动滚动。(组件不会套,页面有recycle-list
时也不会套)。后续会提供配置,可以设置不自动套。 - 在 App.vue 中定义的全局 js 变量不会在 nvue 页面生效。
globalData
和vuex
是生效的。 - App.vue 中定义的全局 css,对 nvue 和 vue 页面同时生效。如果全局 css 中有些 css 在 nvue 下不支持,编译时控制台会报警,建议把这些不支持的 css 包裹在条件编译里,
APP-PLUS-NVUE
- 不能在
style
中引入字体文件,nvue 中字体图标的使用参考:加载自定义字体。如果是本地字体,可以用plus.io
的 API 转换路径。 - 目前不支持在 nvue 页面使用
typescript/ts
。 - nvue 页面关闭原生导航栏时,想要模拟状态栏,可以参考文章。但是,仍然强烈建议在 nvue 页面使用原生导航栏。nvue 的渲染速度再快,也没有原生导航栏快。原生排版引擎解析
json
绘制原生导航栏耗时很少,而解析 nvue 的 js 绘制整个页面的耗时要大的多,尤其在新页面进入动画期间,对于复杂页面,没有原生导航栏会在动画期间产生整个屏幕的白屏或闪屏。
页面组件使用
- Vue2 导入 - 注册 - 使用
- Vue 3.x增加了
script setup
特性,将三步优化为两步,无需注册步骤 导入 - 使用 uni-app
的easycom
机制,将组件引用进一步优化,开发者只管使用,无需考虑导入和注册
uni-app js差异性
uni-app
的js API由标准ECMAScript的js API 和 uni 扩展 API 这两部分组成
标准js和浏览器js的区别
uni-app
的js代码,h5端运行于浏览器中。非h5端(包含小程序和App),Android平台运行在v8引擎中,iOS平台运行在iOS自带的jscore引擎中,都没有运行在浏览器或webview里。
非H5端,虽然不支持window、document、navigator等浏览器的js API,但也支持标准ECMAScript。
请注意不要把浏览器里的js扩展对象等价于标准js。
所以uni-app的非H5端,一样支持标准js,支持if、for等语法,支持字符串、数字、时间、布尔值、数组、自定义对象等变量类型及各种处理方法。仅仅是不支持window、document、navigator等浏览器专用对象。
uni-app css的差异性
- vue 页面是 webview 渲染的
- app-nvue 页面是原生渲染的,其样式比 web 会限制更多,另见nvue的css
- app-uvue 页面是原生渲染的,是 web 的css子集,另见uvue的css
- uni-app 的 css 与 web 的 css 基本一致。
uni-app
支持的通用 css 单位包括 px、rpx- uni-app 支持less、sass、scss、stylus等预处理器(HBuilderX 4.56+ ,vue2 项目也将默认使用 dart-sass 预编译器,vue3默认则是dart-sass)
- 在
uni-app
中不能使用*
选择器。 - 微信小程序自定义组件中仅支持 class 选择器
page
相当于body
节点- 框架建议使用 Flex 布局
- 为方便开发者,在背景图片小于 40kb 时,
uni-app
编译到不支持本地背景图的平台时,会自动将其转化为 base64 格式;图片大于等于 40kb,会有性能问题,不建议使用太大的背景图,如开发者必须使用,则需自己将其转换为 base64 格式使用,或将其挪到服务器上,从网络地址引用。本地背景图片的引用路径推荐使用以 ~@ 开头的绝对路径

uni-app vue语法差异
基本上无差!!!
- App端和H5端支持
v-html
,微信小程序会被转为rich-text
,其他端不支持v-html
。
跨端的富文本处理方案详见:ask.dcloud.net.cn/article/357...(如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代)
- v-show 不支持 template 元素,也不支持 v-else。nvue 页面不支持 v-show
- 若需要禁止蒙版下的页面滚动,可使用
@touchmove.stop.prevent="moveHandle"
,moveHandle
可以用来处理touchmove
的事件,也可以是一个空函数 - 小程序平台:
HBuilderX 3.3.3+
编译器改为vite
,之前版本的编译器为webpack
。 - App 平台:
uni-app 3.2.5+
支持。HBuilderX 3.3.13
起nvue
编译器升级为vite
- vue3 响应式基于
Proxy
实现,不支持iOS9
和ie11
。 - 暂不支持新增的
Teleport
,Suspense
组件。 - 目前
HBuilderX 3.2
起已预置,之前的版本只能使用cli方式 - uni-app 内置了 Pinia 。Vue 2 项目暂不支持(使用vuex)
调试相关

TypeScript 支持 jsx/tsx的支持
uni-app 支持使用 ts 开发,可参考 Vue.js TypeScript 支持 说明。
类型定义文件由 @dcloudio/types
模块提供,安装后请注意配置 tsconfig.json
文件中的 compilerOptions > types 部分,如需其他小程序平台类型定义也可以安装,如:miniprogram-api-typings、mini-types。对于缺少或者错误的类型定义,可以自行在本地新增或修改并同时报告给官方请求更新。
ts
// tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"moduleResolution": "node",
"esModuleInterop": true,
"sourceMap": true,
"skipLibCheck": true,
"importHelpers": true,
"allowSyntheticDefaultImports": true,
"useDefineForClassFields": true,
"resolveJsonModule": true,
"lib": [
"esnext",
"dom"
],
"types": [
"@dcloudio/types"
]
},
"exclude": [
"node_modules",
"unpackage",
"src/**/*.nvue"
]
}

uniapp 支持 JSX 开发,可参考 Vue.js JSX/TSX 支持 说明
shell
npm install @vitejs/plugin-vue-jsx --save-dev

先把注意事项,基本面原理,基础语法差异弄清楚才能更好的为开发做准确准备,任何一门语法框架技术也应该如此!!官网即是最好最佳的学习方式,深入必须要编程基础功底+源码+经验+编程思维结合了~