diff --git a/docs/tutorial/platform.md b/docs/tutorial/platform.md index b54d3820dfc33704aa40ebddebd8b6af4e6061f5..f2f3c4dafc2468347591f2e6347bff56d1b0e87c 100644 --- a/docs/tutorial/platform.md +++ b/docs/tutorial/platform.md @@ -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文件| diff --git a/docs/uni-app-x/compiler/README.md b/docs/uni-app-x/compiler/README.md index 9929bab0e750ce5687b579fd6b56c6d3ebf278cc..a7f434ca0552bd3c868abc6c22dd7222e3ff66c3 100644 --- a/docs/uni-app-x/compiler/README.md +++ b/docs/uni-app-x/compiler/README.md @@ -1,14 +1,28 @@ #### 什么是 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"} diff --git a/docs/uni-app-x/css/readme.md b/docs/uni-app-x/css/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..678fcdd5ffc8e2edb9d5981838a4e24a35c0a388 --- /dev/null +++ b/docs/uni-app-x/css/readme.md @@ -0,0 +1,209 @@ +# 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 + + + + + + +``` + +一般在app.uvue的style里编写全局样式,在页面里使用class引用更为方便。 +```html + +``` + +```html + +``` + +其实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 + +``` + +考虑到未来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"`,关闭原生导航栏。 +然后编写一个自己的导航栏组件,假设名为``,那么推荐的页面代码结构为: + +```html + +``` + +> 注:这里的“原生导航栏”是一个历史沿袭叫法,指配置在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 diff --git a/docs/uni-app-x/performance.md b/docs/uni-app-x/performance.md new file mode 100644 index 0000000000000000000000000000000000000000..37910562f7da5bc84e8c12183db32ec17bb13383 --- /dev/null +++ b/docs/uni-app-x/performance.md @@ -0,0 +1,72 @@ +# 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数量多一点,页面性能就很容易被拖垮。 diff --git a/docs/uni-app-x/readme.md b/docs/uni-app-x/readme.md index f3df46a146490faee5db457d8d229e4028527089..dd2c3263fce733d367431f2fbc7ce11148b30e17 100644 --- a/docs/uni-app-x/readme.md +++ b/docs/uni-app-x/readme.md @@ -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 diff --git a/docs/uni-app-x/web2native.md b/docs/uni-app-x/web2native.md new file mode 100644 index 0000000000000000000000000000000000000000..df83c815edfbc3e7a307678e663593fdd075513d --- /dev/null +++ b/docs/uni-app-x/web2native.md @@ -0,0 +1,19 @@ +# web开发者使用uni-app x注意 + +## 崩溃 + +强类型语言,在开发阶段有各种类型检查,避免运行期的错误。 + +但其实,强类型语言的运行期容错很差,需要大量手写的try catch,否则很容易崩溃。 + +比如给一个number类型的变量赋值一个字符串,在开发阶段会检查,编译不允许通过。 + +```ts +let a:number = "abc" //报错,无法编译 +``` + +但如果从网络动态下载了一个数据,可能会逃过编译器的校验,如果在运行时发生了给number变量赋值或as或parseInt字符串等类型不匹配行为,App会直接崩溃。 + +这是原生开发和web开发非常大的不同。 + +uvue框架内部做了一些错误拦截,减少崩溃,但开发者还是需要注意,在可能不安全的地方要try。