Skills

Skyline Skills微信小程序 Skyline 渲染引擎的 Agent Skills 集合,可帮助你借助 AI 编码工具高效开发 Skyline 微信小程序。

安装

执行以下命令即可将 Skyline Skills 添加到你的项目中:

npx skills add wechat-miniprogram/skyline-skills

更新

如需将 Skyline Skills 更新至最新版本,请运行:

npx skills update wechat-miniprogram/skyline-skills

Skills 列表

Skill 描述 使用场景
skyline-overview Skyline 概览与迁移指南 初次了解 Skyline、评估迁移成本
skyline-config JSON 配置规范 创建项目、配置 app.json/页面 json
skyline-components 组件开发指南 scroll-view、swiper、表单、共享元素等组件
skyline-wxss WXSS 样式支持 CSS 属性兼容性查询、样式编写
skyline-worklet Worklet 动画系统 worklet 动画、SharedValue、timing/spring
skyline-route 自定义路由与转场 页面转场动画、半屏弹窗、返回手势
skyline-scroll-api 滚动控制 API ScrollViewContext、程序化刷新/滚动

微信小程序性能调试工具入口

showPerformanceOverlay

显示 raster 线程和 ui(渲染)线程的使用情况,线程繁忙则显示为红色

  • raster线程:如果发现耗时很高的话,可能是绘制内容太复杂了,例如使用了大量的 backdrop-filter、overflow: hidden、opacity 这些属性会影响光栅化耗时,建议减少这些属性的使用。另外,还可以在频繁更新的节点上添加一个 will-change: contents 这个 wxss 属性来避免大范围的重绘(但这个属性也要避免过多使用,否则会有反效果)
  • ui线程:一般要看是不是没有用上 type=”list”,没用的话布局和 paint 耗时都会比较高
  • 线程相关参考

checkerboardRasterCacheImages

在屏幕上显示一个棋盘格,显示棋盘格的组件表示已经被缓存了

  • 如果发现棋盘格颜色改变,则表示该组件重新渲染
  • 如果滚动时且元素还在屏幕内的时候,颜色一直在变化的话,说明有问题,说明没有缓存,这时候会影响滚动性能。这时候可能是 list-view(type=list)没用对,也可以用 will-change: contents 来手动添加一个绘制边界
  • 不是所有的组件都会形成 RasterCache,需要结构复杂一些才会

Skyline 迁移工具

为了方便开发者从 WebView 迁移到 Skyline,我们将一些最佳实践和常见的兼容问题都整理成一个检测工具 Skylint

Skylint 不仅会罗列出有兼容问题的具体代码行,对一些明确的兼容问题,也提供自动修改代码的操作,旨在最大程度降低迁移成本

更多说明和用法请前往 Github 查看

发布上线

在考虑要上线发布到正式环境时,我们一般会关注版本覆盖稳定性问题,对于这两个问题,我们提供了完备的解决方案。

版本覆盖

由于 Skyline 是在微信较高版本支持,那么是否低版本就完全运行不了微信小程序了?答案是否定的。为了保证线上微信小程序能可靠运行,可任取以下其中一种策略

  1. 提高「基础库最低可用版本」,设置为 Skyline 所支持的版本,该策略意味着放弃低版本用户。

  2. 兼容好 WebView,我们会在不支持 Skyline 的版本自动降级为 WebView 渲染

由于 Skyline 所支持的 CSS 子集是遵循 Web 标准的,因此在样式方面切到 WebView 渲染也能正确渲染,此外对于 Skyline 新增的特性,与微信小程序其它新增的接口类似,低版本需做好兼容,但我们在部分特性针对 WebView 做了兼容处理,具体参考以下表格:

特性 WebView 兼容性 低版本兼容性
worklet 动画 已兼容 需自行做好兼容
手势系统 相当于空节点 需自行做好兼容
自定义路由 无需兼容(无动效) 无需兼容(无动效)
共享元素 无需兼容(无动效) 无需兼容(无动效)
scroll-view 按需渲染 无需兼容(无优化) 无需兼容(无优化)
scroll-view 新增属性和事件 不兼容 需自行做好兼容
grid-view 已兼容 需自行做好兼容
sticky-section/header 不兼容(可手动加上 position: sticky 兼容) 不兼容(可手动加上 position: sticky 兼容)

稳定性

一般而言,代码变更后需要上线发布时,为了保证线上的稳定性,我们都会选择灰度发布,对于新增 Skyline 相关代码的情况也不例外,因此我们提供了完备的灰度方案。

  1. 通过 We 分析 AB 实验进行灰度。

Skyline 默认是需要经过 We 分析的 AB 实验的,也就是微信小程序新版本发布后,默认还是以 WebView 运行,需要在 We 分析的 AB 实验的「微信小程序基础库实验」逐步放量。需要特别留意的是,当 AB 实验的流量分配到 100% 时,并不代表是全量,而是 Skyline 和 WebView 各 50%,若要全量的话,需要先结束实验再选择全量某一个实验组。

  1. 通过微信小程序版本管理中的发布灰度。

微信小程序已经过充分测试,无需再进行 AB 实验的话,我们也提供了以下配置项,可在 app.json 或 page.json 配置上,使 Skyline 不经 AB 实验而默认打开。一般来说,sdkVersioniosVersion+androidVersion 选其一填写即可。

"rendererOptions": {
  "skyline": {
    "disableABTest": true,
    "sdkVersionBegin": "3.0.1", // 基础库最低版本
    "sdkVersionEnd": "15.255.255", // 填最大值,否则之后的新版本会不生效
  }
}
"rendererOptions": {
  "skyline": {
    "disableABTest": true,
    "iosVersionBegin": "x.y.z", // iOS 微信最低版本
    "iosVersionEnd": "15.255.255", // 填最大值,否则之后的新版本会不生效
    "androidVersionBegin": "x.y.z", // 安卓微信最低版本
    "androidVersionEnd": "15.255.255", // 填最大值,否则之后的新版本会不生效
    "ohosVersionBegin": "1.0.5", //  HarmonyOS 微信最低版本
    "ohosVersionEnd": "15.255.255" // 填最大值,否则之后的新版本会不生效
  }
}

兼容

Skyline 目前各端的支持情况见下表

平台 支持版本 备注
安卓 8.0.33+ 支持
iOS 8.0.34+ 支持
开发者工具 Stable 1.06.2307260+ 支持
Windows 未支持 规划中
Mac 未支持 规划中
企业微信 未支持 开发中

可以看出,微信小程序若不是只跑在最新版本的微信移动端,则需要关注兼容 WebView 的情况,这里我们整理了一些兼容方法及常见的兼容问题

兼容方法

样式兼容

Skyline 与 WebView 的主要差异在于样式支持度,因此大部分兼容工作主要集中在样式适配,这里可以利用开发者工具的 WXML 调试工具,通过定位到有问题的节点,分析对应的样式兼容性。

对于具体样式兼容的策略上,由于 Skyline 中部分样式的默认值与 web 不同,因使用默认值而省略的样式需要显示指定,如 flex-direction: row,但此处更推荐开启默认 Block 布局和默认 ContentBox 盒模型,默认值处理与 web 更接近,其它更多信息,详见 Skyline WXSS 样式支持与差异

根据不同 renderer 兼容

有时,单纯用 WXML 和 WXSS 无法做好兼容时,可以通过 JS 判断是否 Skyline 以使用不同的 WXML 或 WXSS 实现。我们在页面或组件实例增加了 renderer 成员,取值为 webviewskyline,参考以下代码

<view class="position {{renderer}}"></view>
.position {
    position: fixed;
}
.position.skyline {
    position: absolute;
}
Page({
    data: {
        renderer: 'webview'
    },
    onLoad() {
        this.setData({
            renderer: this.renderer,
        })
    },
})

常见的兼容问题

  • Skyline 一定需要应用到整个微信小程序吗?

    不需要,Skyline 支持按页面粒度或分包粒度开启,可渐进式迁移。

  • 开启 Skyline 后布局错乱

    一般是默认 flex 布局及 box-sizing 默认为 border-box 导致,推荐开发者开启默认 Block 布局、默认 ContentBox 盒模型

  • 切换 Skyline后,为什么顶部原生导航栏消失?

    不支持原生导航栏,需自行实现,或使用 weui 组件库。推荐页面配置加上 “navigationStyle”: “custom” 以保持与 WebView 兼容

  • 切换 Skyline 后,为什么 position: absolute 相对坐标不准确?

    在 Skyline 模式下,所有节点默认是 relative,可能导致 absolute 相对坐标不准。建议开发者修改节点 position 或者修改相对坐标。

  • 多段文本无法内联

    因不支持 inline 布局导致,需改成 flex 布局实现,或者使用 text 组件包裹多段文本,而不是用 view 组件包裹,也可以使用 span 组件包裹 text 和 image 混合内联。如 <span><image /></span><span><view style="width: 50px;"/></span>

  • 单行文本的省略样式失效

    text-overflow: ellipse 只在 text 组件上生效,不能应用在 view 组件上,同时需要声明 white-space: nowrap 以及 overflow: hidden,建议直接使用 <text overflow="ellipsis"/>

  • 多行文本的省略样式失效

    在单行文本省略的基础上,通过 text 组件的 max-lines 属性设置最长行数,即 <text max-lines="2"></text>

  • z-index 表现异常

    这是由于 Skyline 不支持 web 标准的层叠上下文所致,只有在同层级的节点之前应用 z-index 才有效,可根据实际情况调整取值

  • weui 扩展库无法使用

    平台正在支持扩展库,预计近期上线。建议开发者使用 npm 安装 weui 组件库 后,将 node_ modules/weui-miniprogram 下的miniprogram_ dist 替换为 链接 中的 miniprogram_dist,然后在微信开发中工具中构建 npm 即可。

  • 不支持组件 animate 动画接口

    暂不支持组件 animate 动画接口。如需实现相关效果,可使用 worklet 动画机制 实现

  • svg 渲染不正确

    Skyline 上的 SVG 不支持 选择器匹配,可自行转成内联的方式;不支持 rgba 格式,可使用 fill-opacity 替代;建议用 SVGO 在线工具优化

  • 自定义组件的样式表现不正确

    • 可留意是否存在跨自定义组件的样式匹配,Skyline 下 tag 和 id 选择器不支持跨自定义组件匹配,而 class 则遵循 组件样式隔离机制,可开启 tag 选择器全局匹配以保持与旧版行为对齐
  • WebView scroll-view 横向滚动不生效

    横向滚动需打开 enable-flex 以兼容 WebView,同时 scroll-view 添加样式 display: flex; flex-direction: row;,scroll-view 子节点添加样式 flex-shrink: 0;

  • 当 scroll-view 包含的内容较多时,为什么 boundingClientRect 无法执行?

    由于 scroll-view 的直接子节点(第一层节点)是按需渲染,即直接子节点不在屏时不会渲染,无法获取到节点尺寸,因此当 boundingClientRect 通过 query.selectAll 获取时,无法立即获取节点尺寸,只有在所有节点渲染才能获取。建议开发者尝试调整为逐个获取节点的 boundingClientRect。

  • 切换 Skyline 后,为什么 map / canvas / video / camera 在微信开发者工具渲染失败?

    在 Skyline 模式下,微信开发者工具暂未支持调试原生组件,建议开发者使用真机预览完成调试。

  • 在 Skyline 模式下,为什么微信开发者工具热重载无响应?

    目前 Skyline 模式暂不支持热重载,建议先关闭热重载,重新编译来预览渲染结果。后续平台将支持热重载能力。

最佳实践

按需注入

Skyline 依赖 按需注入 特性。按需注入特性开启后,微信小程序的部分表现会发生变化,有可能带来兼容问题(具体见按需注入特性文档);因此建议在开始适配 Skyline 前,先开启按需注入并妥善测试,以提前排除该特性带来的影响。

渐进式迁移

对于已有的项目,建议渐进式迁移,即逐个页面打开,推荐迁移使用该微信小程序的关键路径上的页面,以便让大多数用户获得更好的体验;对于新增页面,建议默认开启 Skyline;而对于全新项目,建议直接全局打开,除了有更好的体验外,也能使微信小程序的内存占用更低

使用局部滚动

在 WebView 下,页面全局默认是可以滚动的,因此大多数开发者会直接使用全局的滚动,这使得

  1. 无需滚动的元素使用 position: fixed 固定位置,如自定义导航栏,这是用全局滚动模拟了局部滚动,此时滚动条的显示位置会溢出
  2. 针对滚动的自定义功能只能通过配置或 API 的方式提供,如 Page.onPageScroll 等,也使得部分特性无法实现

因此,Skyline 不再提供全局滚动,在需要滚动的区域使用 scroll-view 实现,后续我们也能针对 scroll-view 组件提供更多扩展。

一般来说,界面布局大多数都是导航栏 + 滚动区域的形式,这里提供一种常规做法(兼容 WebView)

<navigation-bar></navigation-bar>
<!-- 通过使用 flex 布局,将 scroll-view 设置 flex:1 以占据页面剩余空间 -->
<scroll-view type="list" scroll-y style="display: flex; flex-direction: column; flex: 1; width: 100%; overflow: auto;">
  <view wx:for="{{items}}" list-item></view>
</scroll-view>

全局样式重置

Skyline 支持的 WXSS 是 WebView 的子集,未来可能会再支持一些必要的或常用的特性,但还是会一直保持 WebView 子集的状态。

因此,为了让 WebView 的兼容表现尽量对齐 Skyline,同时减少重复设置的代码,建议全启开启下述配置项:

rendererOptions: {
  "skyline": {
    "defaultDisplayBlock": true,
    "defaultContentBox": true,
    "tagNameStyleIsolation": "legacy",
    "enableScrollViewAutoSize": true,
  }
}

同时考虑全局或页面级应用如下 WXSS Reset:

page,
view,
text,
image,
button,
video,
map,
scroll-view,
swiper,
input,
textarea,
navigator {
  position: relative;
  background-origin: border-box;
  isolation: isolate;
}
page {
  height: 100%;
}

优化长列表性能

Skyline 下的 scroll-view 组件自带按需渲染的优化,这在很大程度上提升了长列表的渲染性能,这里是以 scroll-view 的直接子节点为粒度来按需渲染的,当其某个子节点接近 scroll-view 的 viewport 时就会被渲染,反之则会回收。

<!-- 以下 scroll-view 的直接子节点有 5 个 view,此时每个 view 都能按需渲染 -->
<scroll-view type="list" scroll-y>
    <view> a </view>
    <view> b </view>
    <view> c </view>
    <view> d </view>
    <view> e </view>
</scroll-view>
<!-- 以下 scroll-view 的直接子节点只有 1 个 view,按需渲染并不能发挥作用 -->
<scroll-view type="list" scroll-y>
    <view>
        <view> a </view>
        <view> b </view>
        <view> c </view>
        <view> d </view>
        <view> e </view>
    </view>
</scroll-view>

此外,长列表的每一项的样式基本是一样的,Skyline 也支持了相似节点的样式共享,使得样式只需要计算一次便能共享给其它相似节点,大大提升了样式计算的性能。一般来说,我们会用 WXML 模板语法 wx:for 来展开列表,因此只需要在列表项声明 list-item 就能启动样式共享(后续版本会识别 wx:for 而自动启用)

<scroll-view type="list" scroll-y>
    <view wx:for="" list-item> {{index}} </view>
</scroll-view>

预加载

微信小程序有个重要优化是会预加载环境,包括 WebView 环境、AppService 线程、提前注入基础库等,而由于目前微信小程序大多还是以 WebView 渲染,为了节省资源,微信客户端并不会自动预加载 Skyline 环境(后续根据实际情况不断优化策略),因此我们提供了 wx.preloadSkylineView 预加载 Skyline 环境的接口,开发者可以在可能跳转到 Skyline 页面的路径上手动调用该接口,建议在 onShow 生命周期里延迟一段时间后调用,使得 Skyline 页面被返回时能够重新预载

使用增强特性

为了使微信小程序的体验能够跟接近原生 App,Skyline 新增了若干个特性,包括 worklet 动画机制、手势系统、自定义路由、共享元素动画等,这些特性使得 Skyline 能够做出一些 WebView 下无法实现或实现效果不够流畅的交互动效。

考虑在 WebView 下都不支持,推荐以一种体验降级的方式去兼容。比如自定义路由,同样是以 wx.navigateTo 接口跳转页面,在 Skyline 下可以以自定义路由动画的方式跳转页面,以获得更好的体验,而 WebView 则 fallback 到朴素的从右到左的页面切换动画,同理,共享元素动画特性亦是如此,也无需额外的兼容代码。

在真机上预览效果

环境准备

Skyline 具体支持版本如下:

  • 微信安卓客户端 8.0.40 或以上版本(对应基础库为 3.0.2 或以上版本)
  • 微信 iOS 客户端 8.0.40 或以上版本(对应基础库为 3.0.2 或以上版本)
  • 微信 OHOS 客户端 1.0.10 或以上版本(对应基础库为 3.11.3 或以上版本)
  • 开发者工具 Stable 1.06.2307260 或以上版本(建议使用 Nightly 最新版)

扫码快速确认环境是否正确

使用开发者工具调试

开发者工具提供了对齐移动端的 Skyline 渲染引擎,支持 WXML 调试、 WXSS 样式错误提示、新增的特性等

按以下步骤切换到 Skyline 模式:

  1. 在 app.json 或 page.json 中配上 renderer: skyline,并按下一节添加好配置项,或者按开发者工具的提示逐个加上配置项
  2. 确保右上角 > 详情 > 本地设置里的 开启 Skyline 渲染调试 选项被勾选上
  3. 使用 worklet 动画特性时,确保右上角 > 详情 > 本地设置里的 编译 worklet 代码 选项被勾选上 (代码包体积会少量增加)
  4. 调试基础库切到 3.0.0 或以上版本

若切换期间出现报错、白屏等问题,可尝试重启开发者工具解决

已知问题:热重载暂未支持

此时,在模拟器左上角能够看到当前的 renderer 为 skyline,见下图

开始迁移

迁移到 Skyline,无需大动干弋,我们保持了上层框架的语法、接口基本不变,只需要做局部的调整,主要是加强了 WXSS 样式、内置组件及部分特性的约束,基本流程如下:

  1. app.json 加上如下必要配置项,若只想在某些页面开启,可将 renderer componentFramework 配置在页面 json 中
"lazyCodeLoading": "requiredComponents",
"renderer": "skyline",
"componentFramework": "glass-easel",
"rendererOptions": {
  "skyline": {
    "defaultDisplayBlock": true,
    "defaultContentBox": true,
    "tagNameStyleIsolation": "legacy",
    "enableScrollViewAutoSize": true,
    "keyframeStyleIsolation": "legacy"
  }
}
  1. 进行组件与 WXSS 适配,参考 Skyline 基础组件支持与差异、Skyline WXSS 样式支持与差异

参考代码模板

按照指引适配后,可以保证在微信低版本或 PC 端 fallback 到 WebView 渲染时,也能表现正确

更多详细指引参考 最佳实践 和 兼容建议

由于 Skyline 默认接入 We 分析的 AB 实验,未配置的情况下,页面渲染仍为 WebView 引擎,可通过以下方式正确切到 Skyline 渲染

  1. 配置 We 分析 AB 实验,加上白名单,操作步骤详见下节
  2. 关闭 We 分析 AB 实验,默认启用 Skyline 渲染,配置方式详见此处第 2 点
  3. 通过快捷切换入口,强切到 Skyline 渲染,操作步骤详见下节

配置 We 分析 AB 实验

迁移完 Skyline 之后,为了让开发者能够针对 Skyline 逐步灰度放量,并且与 WebView 对比性能表现,我们在 We 分析 提供了 AB 实验机制。

因此,需要在 We 分析 配置之后,微信小程序用户才可以命中 Skyline 渲染,需要注意的是,微信小程序开发者也会受 AB 实验影响。操作步骤如下:

首先,进入 We 分析,在 AB 实验 > 实验看板,点击“新建实验”

接着,实验类型选择 微信小程序基础库实验,然后按需选择实验层级并分配流量,如果是小范围调试,可分配 0% 流量,并在 Skyline 渲染 的实验分组里填上测试微信号

最后,创建实验即可生效。后续经 AB 实验验证稳定后,需在 We 分析上先关闭实验再选择 Skyline 全量

点击查看更多 We 分析 AB 实验相关内容

快捷切换入口

考虑到本地调试时,配置 AB 实验会稍微繁琐一些,并且也会需要对比 WebView 的表现,我们提供了快捷切换渲染引擎的入口。

该入口只对开发版/体验版微信小程序生效,入口为:微信小程序菜单 > 开发调试 > Switch Render,会出现三个选项,说明如下:

  • Auto :跟随 AB 实验,即对齐微信小程序正式用户的表现
  • WebView :强制切为 WebView 渲染。强切后,开发版、体验版、正式版均为 WebView 渲染,需手动切到 Auto 才能恢复
  • Skyline :若当前页面已迁移到 Skyline,则强制切为 Skyline 渲染。强切后,开发版、体验版、正式版均为 Skyline 渲染,需手动切到 Auto 才能恢复

如何识别当前页面是否使用 Skyline

  • 通过客户端菜单:

    打开开发版/体验版微信小程序,点击菜单即可查看当前页面是否使用 Skyline 渲染。

  • 通过 vConsole 按钮的右上角的红底文案识别

  • vConsole 的路由日志

    路由日志中会包含页面路由的目标页面、路由类型和目标页面的渲染后端。

    一个可能的日志形如:On app route: pages/index/index (navigateTo), renderer: skyline,代表通过 navigateTo 跳转到了 pages/index/index,渲染后端为 skyline

  • 通过接口判断

    页面和自定义组件示例上有属性 renderer,可以用于判断当前组件的实际渲染后端,如:

    Page({
      onLoad() {
        console.log(this.renderer)
      }
    })
    

滚动容器及其应用场景

流畅的滚动对于提升用户体验至关重要。为了达到原生级别的滚动效果和降低开发成本,Skyline 扩展了旧的 ScrollView 组件,同时针对部分场景,新增了一些滚动容器。诸多的新能力有时会让开发者选择困难,下面对其典型应用场景进行介绍。

长列表

WebView 下的 ScrollView 组件,在快速滑动时容易出现白屏和渲染卡顿。对于长列表的优化,通常离不开按需渲染,即理想状态下仅渲染在屏节点,超出可视区域的节点及时进行回收。

Skyline 下内置了按需渲染的能力,但对于写法有一定要求,列表项需作为直接子节点,形如下面的结构。

<scroll-view type="list" scroll-y>
  <view> a </view>
  <view> b </view>
  <view> c </view>
</scroll-view>

视口大小

ScrollView 的视口大小 = ScrollView 的高度 + 指定的上下缓冲区 CacheExtent

指定 CacheExtent 可优化滚动体验和加载速度,但会提高内存占用且影响首屏速度,可按需启用。

节点进入视口区域时开始渲染,离开视口时回收资源。资源回收的粒度为其直接子节点。当 ScrollView 仅有单个子节点时,为保证其渲染,所有的资源都无法回收,需全量布局和绘制所有内容,性能较差,因此才需要摊平子节点。

出于业务需要 ScrollView 的内容常被封装成组件,导致无法作为直接子节点。这里有一个小技巧,可将封装的组件设为虚拟的,开启 virtualHost: true。真正渲染时,virtual-comp 节点并不存在,列表项仍是摊平的。

<scroll-view type="list" scroll-y>
  <virtual-comp>
    <view> a </view>
    <view> b </view>
    <view> c </view>
  </virtual-comp>
</scroll-view>

完全的按需渲染

微信小程序内的按需渲染分为两个阶段。

  1. 列表项按需创建其 DOM 节点
  2. 列表项按需绘制上屏;

ScrollViewlist 模式实现了按需绘制,但列表项的 DOM 节点 仍是全量创建的。随着节点数增多,会带来内存压力。

为此框架提供了新的 builder 模式,可使用 list-buildergrid-builder 等组件实现 DOM 节点 的按需创建。

上图是 builder 模式在开发者工具中 wxml 的渲染结果,仅在屏列表项会被真正创建节点,离屏后列表项会被回收,滚动时始终几个子节点。

示例代码片段

在开发者工具中预览效果

ScrollView 的三种模式

ScrollView 提供了列表 list、自定义 custom 和 嵌套 nested 三种渲染模式,实际开发时如何选择呢?

列表模式

默认模式,实现了内置的按需渲染能力,但没有进行节点回收。当列表项比较简单,不会带来明显的内存压力时使用。

非长列表时,即使不摊平列表项也不会有明显性能问题,可使用单子节点写法。

<!-- 单子节点写法,全量绘制 -->
<scroll-view type="list" scroll-y>
  <view>
    <view> a </view>
    <view> b </view>
    <view> c </view>
  </view>
</scroll-view>

<!-- 列表项作为直接子节点,有按需绘制优化 -->
<scroll-view type="list" scroll-y>
  <view> a </view>
  <view> b </view>
  <view> c </view>
</scroll-view>

<!-- 列表项作为 list-view 直接子节点,有按需绘制优化,同上 -->
<scroll-view type="custom" scroll-y>
  <list-view>
    <view> a </view>
    <view> b </view>
    <view> c </view>
  </list-view>
</scroll-view>

自定义模式

列表滚动时常会和特殊布局能力结合使用,如滚动到顶部时自动吸顶 sticky 效果,或瀑布流布局。

Skyline 内置了这部分能力,可直接使用 sticky-headergrid-view 组件实现。

list-view 组件的效果跟列表模式是等价的,如果不需要这些特殊布局能力,可任意选择写法。

需要注意的是自定义模式下,ScrollView 直接子节点本身并没有按需绘制优化,按需绘制的能力是 list-view 组件实现的,custom 模式组合了这些能力。

<scroll-view type="custom" scroll-y>
  <sticky-section>
    <sticky-header>
      <view> h </view>
    </sticky-header>

    <!-- 非 list-view 子节点,无按需绘制优化 -->
    <view> 1</view>
    <view> 2 </view>

    <!-- 列表项作为 list-view 直接子节点,有按需绘制优化 -->
    <list-view>
      <view> a </view>
      <view> b </view>
      <view> c </view>
    </list-view>
  </sticky-section>
</scroll-view>

<scroll-view type="custom" scroll-y>
  <sticky-section>
    <sticky-header>
      <view> h </view>
    </sticky-header>

    <!-- 列表项作为 grid-view 直接子节点,有按需绘制优化 -->
    <<grid-view type="masonry">
      <view> a </view>
      <view> b </view>
      <view> c </view>
    </<grid-view>
  </sticky-section>
</scroll-view>

示例代码片段

在开发者工具中预览效果

嵌套模式

这主要是针对一类嵌套滚动场景。如下图所示,SwiperItem 内也有纵向滚动的 ScrollView 组件,当在内部 ScrollView 上滑动时,会与外层 ScrollView 产生手势冲突,导致外层的页面始终无法滚动。

  • 纵轴+横轴+纵轴的嵌套组合
  • 同一方向的滚动容器存在手势冲突
  • 可使用手势协商解决,但过程较为烦琐

为使得内外的滚动衔接更为流畅,框架新增了 <nested-scroll-headernested-scroll-body 组件结合嵌套模式使用,省去了开发者解决手势的麻烦。

<scroll-view type="nested" scroll-y>
  <nested-scroll-header>
    <view></view>
  </nested-scroll-header>
  <nested-scroll-body>
    <swiper>
      <swiper-item>
        <scroll-view 
          type="list"
          associative-container="nested-scroll-view"
        >
          <view>a</view>
          <view>b</view>
        </scroll-view>
      </swiper-item>
      <swiper-item>...</swiper-item>
      <swiper-item>...</swiper-item>
    </swiper>
  </nested-scroll-body>
</scroll-view>

示例代码片段

在开发者工具中预览效果

可拖拽容器

页面内的半屏可拖拽容器是很常见的一种交互,用户可通过滚动扩大列表范围。以往开发者可通过手势协商的能力来实现,但较为繁琐。

框架提供了 draggable-sheet 组件,封装了这一能力,包括

  • 隐藏滚动条
  • 滚动回弹效果
  • 滚动到指定位置(snap 到关键点)
  • 滚动帧回调(实现滚动驱动动画)
<draggable-sheet
  class="sheet"
  initial-child-size="0.5"
  min-child-size="0.2"
  max-child-size="0.8"
  snap="{{true}}"
  snap-sizes="{{[0.4, 0.6]}}"
  worklet:onsizeupdate="onSizeUpdate"
>
  <scroll-view
    scroll-y="{{true}}"
    type="list"
    associative-container="draggable-sheet"
    bounces="{{true}}"
  />
</draggable-sheet>

全局工具栏

基础库 3.3.1 开始支持,低版本需做兼容处理。

可跨页面渲染的组件,使用场景如音乐 APP 的底部工具栏等。在连续的 Skyline 页面跳转时,组件实例为同一个,因此状态可以同步,渲染层级在页面之上(也在自定义 tabbar 之上)。

webview 渲染和 Skyline 渲染之间混跳时,有如下限制:

  1. app-bar 组件仅支持 Skyline 渲染,从 webview 页跳 Skyline 页才会出现,返回到 webview 页则消失。
  2. 连续的 Skyline 页面间跳转,app-bar 组件为同一实例,中间若隔着 webview,则为不同实例,状态不同步。
  3. Skyline 返回到 webview 页面,再次进入 Skylineapp-bar 组件实例会重建,状态也不同步。

示例代码

开发者工具需升级到 Nightly 1.06.2401052,基础库选择 3.3.1

示例-1 混跳场景

在开发者工具中预览效果

示例-2 音乐类播放栏

在开发者工具中预览效果

使用流程

1. 配置信息

  • app.json 中添加 appBar 选项。

示例:

{
  "appBar": {}
}

2. 添加 appBar 代码文件

在代码根目录下添加入口文件,注意不要修改文件命名,app-bar 组件不可声明为虚拟化节点 virtualHost: true

app-bar/index.js
app-bar/index.json
app-bar/index.wxml
app-bar/index.wxss

3. 编写 appBar 代码

用自定义组件的方式编写即可,该自定义组件完全接管 appBar 的渲染。另外,自定义组件新增 getAppBar 接口,可获取当前页面下的 appBar 组件实例。

1. 响应事件

为防止遮挡页面,app-bar 组件根节点默认添加了 pointer-events: none;,组件内的节点需响应点击时,需加上 pointer-events: auto;

<view class="tool-bar"></view>
.tool-bar {
  pointer-events: auto;
  position: absolute;
}

2. 获取组件实例

Page({
  getInstance() {
    if (typeof this.getAppBar === 'function' ) {
      const appBarComp = this.getAppBar()
      appBarComp.setData({})
    }
  }
})