提交 ffd04f88 编写于 作者: W wanganxp

完善教程

上级 76bd27c4
......@@ -26,8 +26,9 @@ uni-app 已将常用的组件、JS API 封装到框架中,开发者按照 uni-
|值|生效条件|
|:-|:-|
|VUE3|HBuilderX 3.2.0+ [详情](https://ask.dcloud.net.cn/article/37834)|
|APP-PLUS|App|
|VUE3|HBuilderX 3.2.0+ [详情](https://ask.dcloud.net.cn/article/37834) (uni-app js引擎版)|
|APP|App|
|APP-PLUS|App(uni-app js引擎版)|
|APP-PLUS-NVUE或APP-NVUE|App nvue 页面|
|APP-ANDROID|App Android 平台 仅限 uts文件|
|APP-IOS|App iOS 平台 仅限 uts文件|
......
#### 什么是 uni-app x 编译器
`uni-app x`编译器是在Vite基础上进行扩展开发的,集成了uts编译器,从而实现一套uts、uvue代码多端运行。
它的大部分特性(如条件编译)和配置项(如环境变量)与`uni-app`vue3的编译器一致,[详见](https://uniapp.dcloud.net.cn/tutorial/compiler.html)
`uni-app x`的编译器由uvue编译器、uts语言编译器共同组成,还调用了kotlin、swift编译器。
编译器把开发者书写的uvue和uts代码进行编译,配合运行时实现了跨平台。
uvue编译器是在Vite基础上进行扩展开发的。
它的大部分特性(如条件编译)和配置项(如环境变量)与`uni-app`的vue3编译器一致,[详见](https://uniapp.dcloud.net.cn/tutorial/compiler.html)
#### 编译缓存 @cache
`uni-app x`编译器引入了编译缓存机制,以优化开发体验。
在App端,`uni-app x`首先将uts和uvue编译为平台原生语言(如Kotlin),然后经过平台配套的编译器进行打包运行。由于平台原生语言的打包编译过程耗时较长,因此编译器引入了缓存机制来加快开发过程。
在编译时,开发者的uts和uvue代码的编译结果会被持久化为缓存。当下次运行时,如果代码没有发生变动,编译器会优先使用缓存中的编译结果,从而加快编译速度。
在App端,`uni-app x`首先将uts和uvue编译为平台原生语言(如Kotlin),然后经过平台配套的编译器进行打包运行。
App原生语言的编译过程耗时较长,因此编译器引入了缓存机制来加快开发过程。
在编译时,开发者的uts和uvue代码的编译结果会被持久化为缓存,存在unpackage目录下。
当下次运行时,如果代码没有发生变动,编译器会优先使用缓存中的编译结果,从而加快编译速度。
如果您不想使用缓存,可以在HBuilderX运行窗口勾选`清理构建缓存`
这个机制类似于传统强类型语言开发中的Build和clean。
![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-x/clean-up-the-build-cache.jpg)#{.zooming width="400px"}
# uvue css使用
uni-app x 在 app平台实现了 web css的子集。开发所需的界面均可排布编写出来。
uni-app x 推荐使用flex布局。这是一种清晰易用、全平台支持的布局。不管web、Android、iOS、微信skyline、快应用,均支持flex布局。
App端仅支持flex布局。
## 页面布局
页面布局有2个注意事项,flex方向和页面级滚动。
### flex方向
在web中,flex默认是横向的,但app默认是纵向的。为了多端兼容,建议开发者显式声明flex方向,不使用默认值。
```html
<view style="flex-direction:row">
<!-- 这里的组件们都是横排 -->
</view>
<view style="flex-direction:column">
<!-- 这里的组件们都是竖排 -->
</view>
```
一般在app.uvue的style里编写全局样式,在页面里使用class引用更为方便。
```html
<style>
.uni-row{
flex-direction: row;
}
.uni-column{
flex-direction: column;
}
</style>
```
```html
<template>
<scroll-view class="uni-column" style="flex:1">
<view class="uni-row">
<text></text>
<text></text>
<!-- 2个text组件横排 -->
</view>
<view class="uni-column">
<text></text>
<text></text>
<!-- 2个text组件竖排 -->
</view>
</scroll-view>
</template>
```
其实flex布局概念非常简单清晰。解释下上面的代码。
1. 页面根节点是一个竖排的(class="uni-column")、全屏的(style="flex:1")scroll-view,那么它的子view们就是竖排。
2. 二级view里的第一个view,设为横排,里面又放了2个三级组件text,那么这2个三级组件text是横排,即左右2个字。
想清楚页面布局,设好row还是column,界面写起来很快。
### 页面级滚动@pagescroll
web开发中,页面是必然可以滚动的。当然也可以给某些div设局部滚动。
而原生开发中,页面不能滚动。如果你需要某个地方滚动,那么要在相应位置放scroll-view或list-view等可滚动组件,在这些组件内部滚动。
如果你想要整页滚动,那么可以在页面最外层套一个scroll-view,看起来就和web开发的页面滚动一样了。
在老版nvue中,如果开发者顶层不是scroll-view,编译器会自动在外面套一层scroll-view,来变相实现页面滚动。
但在uvue中,废弃了这个策略。因为开发者的页面情况较复杂,而且vue3支持多个一级组件,之前的策略可能会多给页面套一层不必要的scroll-view。
在追求高性能时,多一层scroll-view是不能忍受的。
uvue的策略是,在新建页面时,提供一个选项,让开发者选择是否需要页面级滚动。如需要则自动在页面代码里template的根节点加一个scroll-view。
如果开发者不需要,随时可以自己修改代码。
```html
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
```
考虑到未来web平台和基于webview的小程序的兼容,自动套在页面顶层的scroll-view写在了[条件编译](../../tutorial/platform.md)里。
这样在web浏览器里就无需多套一层scroll-view,自然的使用浏览器的页面滚动就好了。
尤其在Android webview中,scroll-view其实是可区域滚动的div,滚动区变长后,性能远不如页面的自然滚动。
上述代码中给scroll-view的style设为`flex:1`,意思是铺满剩余空间。设在顶层节点上,意味着铺满屏幕。
当然,如果页面的pages.json里配置使用了原生导航栏,那么页面区整体是在导航栏下面。
- 自定义导航栏
如果开发者想要自定义导航栏,首先在pages.json里对应页面的style里设置`"navigationStyle": "custom"`,关闭原生导航栏。
然后编写一个自己的导航栏组件,假设名为`<uni-navigationbar>`,那么推荐的页面代码结构为:
```html
<template>
<uni-navigationbar title="自定义导航栏标题">
</uni-navigationbar>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
```
> 注:这里的“原生导航栏”是一个历史沿袭叫法,指配置在pages.json里的导航栏,不属于页面代码区。事实上在uni-app x里所有界面都是原生的。
- 页面滚动相关的生命周期、api
在uni-app的规范中,页面滚动有一批相关的生命周期、api,比如:`onPageScroll``onReachBottom``uni.pageScrollTo()`
在app端,会判断页面根节点是否为scroll-view(不认list-view等其他滚动容器)。
* 如果是,页面滚动相关的生命周期和API继续生效,效果如前。
* 如果不是scroll-view,全部失效。
## css模块
|模块 |支持情况 |备注 |
|:-: |:-: |:-: |
|背景与边框 |√ |不支持背景图 |
|盒子模型 |√ | |
|Flex 布局 |√ | |
|Inline 布局 |× | |
|Inline-Block 布局 |× | |
|Block 布局 |√ | |
|字体 |√ |支持ttf、otf,不支持woff和woff2和可变字体 |
|Positioned 布局 |√ | |
|CSS Animation |√ | |
|CSS Transition |√ | |
|CSS Variable |√ | |
|媒体查询 |√ | |
## 选择器
|类别 |示例 |支持情况 |备注 |
|:-: |:-: |:-: |:-: |
|通配选择器 |* {} |× | |
|类选择器 |.class {} |√ | |
|元素选择器 |tag {} |× | |
|ID 选择器 |#id {} |× | |
|属性选择器 |[attr] {} |× | |
|分组选择器 |a, b {} |√ | |
|直接子代选择器 |a > b {} |√ | |
|后代选择器 |a b {} |√ | |
|一般兄弟选择器 |a ~ b {} |√ | |
|紧邻兄弟选择器 |a + b {} |√ | |
|伪类选择器 |:active {} |× |:first-child 和 :last-child |
|伪元素选择器 |::before {}|× |::before 和 ::after |
## 长度单位
|类别 |支持情况 |备注 |
|:-: |:-: |:-: |
|px |√ | |
|rpx |√ | |
|百分比 |√ | |
|rem | | |
|em | | |
|vw | | |
|vh | | |
|vmin | | |
|vmax | | |
|ratio | | |
|env() | | |
|calc() | | |
## 颜色
|类别 |支持情况 |备注 |
|:-: |:-: |:-: |
|color keywords |√ | |
|#RRGGBB / #RGB |√ | |
|rgb[a] |√ | |
|transparent |√ | |
|currentColor | | |
|hsl | | |
|hsla | | |
## At-rules
|类别 |支持情况 |备注 |
|:-: |:-: |:-: |
|@font-face |√ | |
|@charset |× | |
|@color-profile |× | |
|@container |× | |
|@counter-style |× | |
|@documentNon-standardDeprecated|× | |
|@font-feature-values |× | |
|@font-palette-values |× | |
|@import |√ | |
|@keyframes |× | |
|@layer |× | |
|@media |× | |
|@namespace |× | |
|@page |× | |
|@property |× | |
|@supports |× | |
## 样式清单
\ No newline at end of file
# uni-app x 性能优化
Android开发,其性能优化和web开发有几处不同,需要注意:
## Android对dom的数量和层次更苛刻
dom数量越多,渲染越慢。
以日历为例,web开发一般是每天一个view,里面再嵌套农历、假日等,一个日历可能有几百个dom元素。如果Android上这么做,会非常卡。
那么原生Android开发怎么做的呢?使用Android的开发者模式审查元素边界,可以发现rom自带的日历,并不是每个格子一个view,而是整个月都是一个view。
![]()
Android上为了避免view数量过多,提供了原始的draw api,把线条和文字绘制上去。
在 uni-app x 中,也提供了同样的方法,允许开发者调用绘制API。
hello uni-app x 示例中,有一个日历的模板页面,就是通过draw api来绘制的,性能非常高。[源码详见](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/master/pages/template/calendar/calendar.uvue)
尤其是组件作者,更需要关注dom数量的问题。
再举一个例子,uni-app x 内部开发基础组件时,第一个版本的slider组件,使用了7个view,利用view的移动和不同颜色view的width变化来实现。当页面中有100个slider时,会变成非常卡。
后来 slider组件改为 draw api 实现,只需要一个view。与许多原生应用相比,uni-app x的 slider组件性能更优秀。
uni-app x还提供了工具帮助开发者监控页面的dom数量。
HBuilderX真机运行到Android时,每个页面进入时会都打印页面初始化的数据:dom数量、排版次数、渲染耗时等。
![]()
当然耗时数据不能以真机运行为准,调试基座因为热更新和sourcemap追踪等很多调试功能,导致性能比真实打包差。正式打包后性能更优。
## 界面元素动画
动画,分不跟随手势的固定动画,和跟随手势的动效两种。
固定动画使用css transition动画,或者使用 [animation-view组件](https://ext.dcloud.net.cn/plugin?id=10674),这个组件本质是lottie动画。
跟随手势的动效,需要写逻辑代码。
uni-app x中,没有通信阻塞,可以直接监听touch和滚动事件。不再需要renderjs、bindingx、wxs、worklet动画这些为了解决通信阻塞的补丁技术。
在touch和滚动事件中,移动dom元素时,有2个注意:
1. 请使用transition方式,而不是给dom的left/top/width/height等position参数重新赋值。这个在web开发也一样,直接改position参数不如使用transition。因为每次修改position参数都要过排版,而transition不用。
2. 请拿到dom的ref,调用js api操作,而不是通过模板style绑定data操作。因为操作data需要vue框架做diff对比。在touch和滚动中,16毫秒一帧才能达到最平滑的效果,多了几毫秒就可能掉帧。
在大多数开发框架中,吸顶这个行为需要底层封装。uni-app x无需特别封装,直接监听滚动事件,通过dom的transition方式动态修改top值,就能在指定条件下实现固顶。
源码参考hello uni-app x中的吸顶示例,[详见](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/master/pages/template/scroll-sticky/scroll-sticky.uvue)
## 避免复杂逻辑卡UI
开发者的代码默认是在ui主线程运行的。除非单独写代码调用子进程或协程。
如果在ui繁忙时,比如页面进入动画时,开发者的代码做了很多耗时操作,会卡动画。这个原生开发也如此。
页面的onload触发,和进入动画是同时发生的,所以需注意onload生命周期中代码的编写。
由于uni-app x提供的联网和图片加载是在单独进程或协程中的,所以这2个行为不会卡ui。
如果onload里某些代码卡了进入动画,也可以挪到页面的onready生命周期中,该事件触发的更晚一些。
页面dom元素过多的话,也会影响进入动画,所以尽量节省dom数量。
## 长列表
uvue页面模板里,list-view组件使用v-for来循环添加list-item,自动就是recycle-view的。无论多长的列表,系统也会自动回收和节约资源,和原生应用一样的体验,但开发更简单。
请避免使用其他方式构建长列表,比如scroll-view。
另外注意list-item里的组件数量,它是dom元素的放大器。每个list-item里的dom数量多一点,页面性能就很容易被拖垮。
......@@ -179,7 +179,6 @@ uni自带API,如下为目前支持的清单。
* [x] uni.closePreviewImage
* [x] uni.startPullDownRefresh
* [x] uni.stopPullDownRefresh
* [ ] uni.getWindowInfo
### 组件
* [x] uni.createVideoContext
......@@ -206,8 +205,9 @@ uni自带API,如下为目前支持的清单。
* [x] uni.getSystemInfo
* [x] uni.getSystemInfoSync
* [x] uni.getDeviceInfo
* [x] uni.getAppBaseInfo
* [x] uni.getSystemSetting
* [x] uni.getWindowInfo
* [x] uni.getAppBaseInfo
* [x] uni.getSystemSetting
* [x] uni.getAppAuthorizeSetting
* [x] uni-getbatteryinfo //已有uts插件
* [x] uni-memeorywarning //已有uts插件
......@@ -240,7 +240,7 @@ uni-app 的自动化测试教程详见:[https://uniapp.dcloud.net.cn/worktile/
除上述文档中声明已经完成的,还有如下需要注意:
- 全端支持:一期只有Android。对于其他平台,开发者可将uvue文件后缀改为vue,如果没有写Android专有代码,那么也可以使用uni-app js引擎版编译到其他平台,包括iOS App、web及各家小程序。后期官方会提供更完善的 uni-app x的全端支持。
- 全端支持:一期只有Android。对于其他平台,开发者可将uvue文件后缀改为vue或nvue,如果没有写Android专有代码,那么也可以使用uni-app js引擎版编译到其他平台,包括iOS App、web及各家小程序。尤其在app-iOS上,由于设备性能本就优秀,所以nvue的方案的性能也足够满足挑剔的开发者。后期官方会提供更完善的 uni-app x的全端支持。
- uvue语法:虽然uvue是按vue3实现的,但一期uvue不支持setup,只支持选项式。
- 一期不支持:横屏切换、暗黑模式、自定义转场、多语言、无障碍
- 一期不支持:云开发(已在开发中)、uni-ad。另外包括微信、支付宝、个推等三方sdk封装一期均未启动
......@@ -257,6 +257,8 @@ uni-app 的自动化测试教程详见:[https://uniapp.dcloud.net.cn/worktile/
4. 对于script,如果你之前使用ts,那么改造成本会很低。如果使用js,那需要改造成uts,差别最大的就是补类型,没法再使用弱类型了。
5. 组件的写法基本没有差别,只需注意uni-app x初期支持的组件不全
您可以先把Android版迁移到uni-app x上,iOS维持原先方案。由于iphone设备性能的优势,uni-app js版的性能应该也可以满足大多数需求。
官方近期会提供把[uni小程序sdk](https://nativesupport.dcloud.net.cn/#)集成到uni-app x的方案。届时你的uni-app js版老项目可以作为uni-app x新项目的一个小程序来使用。
## 原生/rn/flutter页面兼容指南
......@@ -270,21 +272,43 @@ uni-app x 毕竟是原生应用,内嵌flutter、rn这些没有任何问题,
# FAQ
- uni-app x 支持uvue页面和vue页面混写吗?
仅支持uvue页面。后期考虑中。历史vue页面也可以通过 uni小程序sdk 嵌入到uni-app x中。
- uni-app x 的app端能离线打包吗?
初期不能,后期会提供
- uni-app x 能热更新吗?
开发期间可以热刷,但打包后不能热更新。开发者可自行封装原生的插件动态加载方案。
- uni-app x 能使用npm库吗?
uni-app x 的app端里没有js引擎,所有js库都不能用。除非npm上有uts的库。当然把ts的库改造成uts的库并不难。uni-app x编译到web和小程序时,js库仍然可用。
uni-app x 的app端里没有js引擎,不能使用js库。除非npm上有uts的库。
当然把ts的库改造成uts的库并不难,如果ts库没有使用uts不支持的web专用语法,那么可以直接使用。
uni-app x编译到web和小程序时,所有js库仍然可用。
- uni-app x 会搞插件大赛吗?
会。很快启动,鼓励大家做基于uts和uvue的插件。
- uni-app x 能调用所有原生API吗?
可以。在app端,kotlin和swift能调的,uts就能调。
- uni-app x 能集成原生sdk吗?
可以,通过uts插件,[https://uniapp.dcloud.net.cn/plugin/uts-plugin.html](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html)
- uvue页面里的script可以直接调用原生代码吗?还是必须封装成uni_modules方式的uts原生插件?
uvue的script里写的就是uts,uts就可以直接调原生代码。无所谓它在uni_modules里还是外。
uvue的script里写的就是uts,uts就可以直接调原生代码。无所谓它在`uni_modules`里还是外。但如果是大段的原生代码调用,还是推荐封装为独立的`uni_modules`
- uni-app x 的开发只能用HBuilderX吗?
是的。为三方ide做插件是一个投资大且充满不确定性的事情,官方有限精力会聚焦在自身产品优化上。
- uni-app x 支持最低的Android版本多少?
Android 5+。Android4.4可能也可以运行,但官方发版前不会对4.4测试。
- 未来 uni-app js引擎版还维护吗?
维护。服务js开发者仍然是DCloud的重点。但nvue和5+将不再维护。
并非所有应用都需要达到微信、抖音的性能,js引擎版如能满足你的性能需求,那继续使用js引擎版。
未来vue页面也会支持uts组件。无论js引擎版还是x版,都支持uts插件生态,未来的原生扩展api和插件会是复用的。
包括官方的组件和API也会复用,比如电量API[uni.getbatteryinfo](https://ext.dcloud.net.cn/plugin?id=9295),和[lottie组件](https://ext.dcloud.net.cn/plugin?id=10674),它们使用uts开发,在 uni-app js引擎版和x版上,调用的都是一套代码。
\ No newline at end of file
# web开发者使用uni-app x注意
## 崩溃
强类型语言,在开发阶段有各种类型检查,避免运行期的错误。
但其实,强类型语言的运行期容错很差,需要大量手写的try catch,否则很容易崩溃。
比如给一个number类型的变量赋值一个字符串,在开发阶段会检查,编译不允许通过。
```ts
let a:number = "abc" //报错,无法编译
```
但如果从网络动态下载了一个数据,可能会逃过编译器的校验,如果在运行时发生了给number变量赋值或as或parseInt字符串等类型不匹配行为,App会直接崩溃。
这是原生开发和web开发非常大的不同。
uvue框架内部做了一些错误拦截,减少崩溃,但开发者还是需要注意,在可能不安全的地方要try。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册