From 4bdaef60665411fec5625d622af71db6d33ce44e Mon Sep 17 00:00:00 2001 From: huajingwen Date: Tue, 2 Jun 2026 10:48:07 +0800 Subject: [PATCH 01/27] init --- .agents/skills/mpx2skyline/SKILL.md | 194 +++++ .../references/skyline-component-reference.md | 266 ++++++ .../references/skyline-configuration.md | 239 ++++++ .../references/skyline-migration-practice.md | 770 ++++++++++++++++++ .../references/skyline-style-reference.md | 295 +++++++ .../references/skyline-worklet-animation.md | 647 +++++++++++++++ 6 files changed, 2411 insertions(+) create mode 100644 .agents/skills/mpx2skyline/SKILL.md create mode 100644 .agents/skills/mpx2skyline/references/skyline-component-reference.md create mode 100644 .agents/skills/mpx2skyline/references/skyline-configuration.md create mode 100644 .agents/skills/mpx2skyline/references/skyline-migration-practice.md create mode 100644 .agents/skills/mpx2skyline/references/skyline-style-reference.md create mode 100644 .agents/skills/mpx2skyline/references/skyline-worklet-animation.md diff --git a/.agents/skills/mpx2skyline/SKILL.md b/.agents/skills/mpx2skyline/SKILL.md new file mode 100644 index 0000000000..75c6a3de01 --- /dev/null +++ b/.agents/skills/mpx2skyline/SKILL.md @@ -0,0 +1,194 @@ +--- +name: mpx2skyline +description: | + 微信小程序 WebView 适配 Skyline 渲染引擎指南,覆盖布局、样式、组件、配置四大维度。 + 当用户要求对已有微信小程序页面进行 Skyline 适配改造、创建符合 Skyline 兼容规范的页面、 + 排查 Skyline 下样式不生效/组件不渲染/布局异常/层级错乱等问题、或查询某项能力在 + Skyline 下的支持情况时强制调用。当用户问题不涉及 Skyline 适配时不应调用,如 + Mpx 输出 RN 问题、支付宝小程序问题、纯 webview 小程序开发问题等。 +metadata: + version: "1.0.0" +--- + +# 微信小程序适配 Skyline 渲染引擎指南 + +## 背景介绍 + +Skyline 是微信小程序新一代渲染引擎,旨在替代 WebView 渲染以获得更接近原生的性能和体验。与 WebView 模式相比,Skyline 在布局模型、层叠机制、样式能力、组件支持、页面行为上存在系统性差异。 + +本 SKILL 面向以下两类任务: + +1. **任务一**:对已有的 WebView 页面进行 Skyline 适配改造(已在 WebView 模式下运行,需补齐 Skyline 兼容性)。 +2. **任务二**:从零创建一个符合 Skyline 兼容规范的页面。 + +## 知识库索引 + +| 知识库 | 说明 | +| --- | --- | +| [Skyline 基础组件支持与差异参考](./references/skyline-component-reference.md) | 查询组件支持情况与差异,涉及不支持组件的替代方案、Skyline 新增组件、组件使用注意事项 | +| [Skyline WXSS 样式能力参考](./references/skyline-style-reference.md) | 查询样式属性/选择器/单位是否支持,逐属性支持详情与 WebView 差异对比 | +| [WebView→Skyline 适配改造最佳实践](./references/skyline-migration-practice.md) | 进行适配改造时读取,覆盖布局适配、样式适配、组件适配、层叠适配的完整实操方案 | +| [Skyline 配置项与接入规范参考](./references/skyline-configuration.md) | 切换渲染模式、接入代码配置、分包规范、上线放量等项目级配置时读取 | +| [Worklet 动画与手势系统参考](./references/skyline-worklet-animation.md) | 使用 worklet 动画、手势系统、自定义路由等 Skyline 增强特性时读取 | + +### 知识库使用建议 + +参考文档体量较大,**不要一次性预读全部参考**,按需取用即可: + +1. **入口只读本 SKILL.md**:完整读完本文档(含下方通用约束与任务流程)足以覆盖 80% 常见场景的判断;不要在动笔前预读 references 目录。 +2. **触发式读取**:只在任务流程或通用约束中**明确指向**某份参考时读取,且仅读取与当前问题相关的小节(参考文档均含目录与章节锚点,使用 grep / 锚点跳读,不要整文件 Read)。 +3. **典型任务的最小阅读集**(仅当本 SKILL.md 已无法判断时再补充): + - 已有页面 Skyline 适配改造:识别问题维度后再读对应参考的相关小节,通常 1–2 份足够(如布局+样式改造主要查 `skyline-migration-practice.md`)。 + - 新建 Skyline 兼容页面:先按本 SKILL.md 的通用约束起手,遇到能力存疑(某属性是否支持、某组件是否存在)时再点查对应参考。 + - 排查 Skyline 下特定问题:直接定位到问题维度的参考文档相关小节。 + +## 通用约束与适配原则 + +### 跨渲染模式兼容约束 + +产物代码须在 WebView 模式与 Skyline 模式下均能正常运行。引入「Skyline 支持但 WebView 不需要」的写法时,**不要替换 WebView 原有写法**,而应: + +- 通过运行时判断 `this.renderer === 'skyline'` 隔离 Skyline 专属逻辑; +- WebView 原有写法保持不变,避免适配引入 WebView 行为退化。 +- 特定版本支持的 Skyline 特性按支持处理,不做低版本兼容(如 `position: fixed` 8.0.43+ 支持、`:nth-child` 8.0.50+ 支持)。 + +该原则贯穿布局 / 样式 / 组件 / 配置四个维度。 + +### 布局(layout)约束 + +1. **默认布局差异**:Skyline 默认 `display: flex`,WebView 默认 `display: block` → 配置 `defaultDisplayBlock` 或改造为显式 flex 写法。 +2. **页面滚动**:Skyline 不支持页面滚动,`onPullDownRefresh` / `onReachBottom` / `onPageScroll` 不会触发 → 使用 `scroll-view type="list"` 替代,页面需声明 `disableScroll: true`。 +3. **自定义导航**:Skyline 不支持默认导航 → 自定义导航栏,页面需声明 `navigationStyle: 'custom'`。 +4. **z-index 与层叠**:z-index 仅兄弟节点生效,无层叠上下文机制 → 需重构层级结构为兄弟节点,全局层级使用 `root-portal`。详见 [适配最佳实践 · z-index 与层叠适配](./references/skyline-migration-practice.md#z-index-与层叠适配)。 +5. **inline / inline-block**:Skyline 不支持 inline 和 inline-block 布局 → 使用 `` 组件、`` 组件或 flex 布局替代。 + +### 样式(style)约束 + +1. **选择器**:不支持通配选择器 `*` 和属性选择器 `[attr]`;伪元素仅 `::before` / `::after` 且**必须双冒号**;`:nth-child` 需 8.0.50+。详见 [样式能力参考 · 选择器支持](./references/skyline-style-reference.md#选择器支持)。 +2. **单位**:避免 `em` / `currentColor`,使用 `rpx` / `px` / `rem`。 +3. **overflow**:`overflow: scroll` 不支持 → 使用 `scroll-view` 组件;不支持单独设置 `overflow-x` / `overflow-y`。 +4. **text 限定属性**:`text-decoration` / `text-overflow` 仅 `text` 节点生效 → `view` 内文字需用 `` 包裹。 +5. **边框一致性**:`border-radius` 非 0 时四边 `border-color` / `border-style` 需一致。 +6. **box-sizing 默认值**:Skyline 默认 `border-box`(WebView 默认 `content-box`),遇到 padding 未撑开布局时手动指定 `box-sizing: content-box`。 +7. **伪元素 animation**:Skyline 下伪元素的 `animation` 不生效 → 使用真实节点 + CSS animation。 +8. **font-weight**:部分机型不支持 `font-weight: 500` / `600` 数值加粗,需使用 `bold` / `700`。 +9. **box-shadow**:不支持多个叠加。 + +### 组件(component)约束 + +1. **scroll-view 必须指定 type**:``,Skyline 下缺少 type 属性将无法正常工作。 +2. **不支持组件**:`web-view` / `movable-area` / `movable-view` / `editor` / `progress` / `navigation-bar` → 使用替代方案,详见 [组件支持参考](./references/skyline-component-reference.md)。 +3. **自定义组件样式隔离**:`tag` / `id` 选择器不支持跨自定义组件匹配,`class` 遵循组件样式隔离机制。 +4. **组件根节点**:默认 `block` + `relative`,宽高 `100%` 可能失效。 + +## 任务一:对已有 WebView 页面进行 Skyline 适配改造 + +### 输入 + +基于 WebView 模式编写的 `.mpx` 页面(已在微信 WebView 模式下运行,但未适配 Skyline)。 + +### 输出 + +以用户指示为准;若无特殊指示则默认在原文件中进行修改。输出修改后代码时应输出完整页面代码,避免使用省略号,确保用户可以直接复制或应用修改。 + +### 任务流程 + +#### 1. 页面配置适配 + +- 页面 json 新增 `renderer: 'skyline'`、`componentFramework: 'glass-easel'`、`disableScroll: true`、`navigationStyle: 'custom'`。 +- 读取 [配置参考](./references/skyline-configuration.md) 确认全局 skyline 配置(`lazyCodeLoading` / `rendererOptions` 等)是否已就绪。 + +#### 2. 布局适配改造 + +- 读取 [适配最佳实践 · 布局适配](./references/skyline-migration-practice.md#布局适配),对页面的布局与层叠逐一核对 Skyline 兼容性。 +- 默认 flex 布局差异处理(`defaultDisplayBlock` 或显式 flex 写法)。 +- 页面滚动 → `scroll-view type="list"` 替代。 +- 自定义导航替代默认导航。 +- inline / inline-block → `` / `` 替代。 + +#### 3. 样式适配改造 + +- 读取 [样式能力参考](./references/skyline-style-reference.md) 检查 ` + + + + {{item}} + +``` + +### 伪元素适配(单冒号→双冒号) + +Skyline 下伪元素只支持 `::before` 和 `::after`,且必须以双冒号 `::` 形式声明。单冒号写法在 Skyline 下不生效。 + +**全局搜索替换**:在需要适配 Skyline 的文件或文件夹下,搜索 `([^:]):((before)|(after))` 替换为 `$1::$2`。 + +```css +/* ❎ Bad — 单冒号,Skyline 不识别 */ +.item:before { content: ''; } +.item:after { content: ''; } + +/* ✅ Good — 双冒号 */ +.item::before { content: ''; } +.item::after { content: ''; } +``` + +其他伪元素(如 `::-webkit-scrollbar`)在 Skyline 下不支持,可使用真实节点替代。 + +### 伪类适配 + +| 伪类 | 支持情况 | 替代方案 | +| --- | --- | --- | +| `:first-child` / `:last-child` | ✓ 支持 | 直接使用 | +| `:not` / `:only-child` / `:empty` | ✓ 支持(8.0.49+) | 直接使用 | +| `:nth-child` | ✓ 支持(8.0.50+) | 低版本用动态类 + index | +| `:active` | ✓ 支持 | 直接使用 | +| 其他伪类 | × 不支持 | 使用动态类或兄弟/后代选择器实现 | + +### 单位适配 + +| 不支持的单位/值 | 替代方案 | +| --- | --- | +| `em` | 使用 `rpx` / `px` / `rem` | +| `currentColor` | 显式指定颜色值 | + +### overflow 适配 + +Skyline 下 `overflow: scroll` 不支持,只能通过 `scroll-view` 组件实现滚动。不支持单独设置 `overflow-x` / `overflow-y`。 + +```css +/* ❎ Bad — Skyline 不支持 */ +.scrollable { + overflow-y: scroll; +} +.overflow-x-hidden { + overflow-x: hidden; +} + +/* ✅ Good — 使用 scroll-view 组件 */ +/* ... */ +``` + +### box-sizing 差异处理 + +Skyline 下 `box-sizing` 默认为 `border-box`,WebView 下默认为 `content-box`。这个差异可能导致 padding 撑开布局的表现不同。 + +**遇到 padding 未撑开布局异常时**,手动指定 `box-sizing: content-box`: + +```css +.container { + /* Skyline 默认 border-box,如需 content-box 行为需显式声明 */ + box-sizing: content-box; + padding: 20rpx; +} +``` + +**全局配置**:8.0.42+ 可配置 `defaultContentBox` 将默认盒模型改为 `content-box`: + +```json +{ + "rendererOptions": { + "skyline": { + "defaultContentBox": true + } + } +} +``` + +### 文本溢出省略适配 + +`text-overflow: ellipsis` 在 Skyline 下只在 `text` 组件上生效,不能应用在 `view` 组件上。 + +**单行省略**: + +```html +{{text}} +``` + +```css +.ellipsis { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +``` + +**多行省略**: + +```html +{{text}} +``` + +**注意**:flex 布局下的子节点 `text` 换行&溢出隐藏可能存在失效问题(已反馈给微信)。 + +### 字体 PostScript name 兼容 + +部分机型不支持 `font-weight: 500` / `600` 等数值加粗,只能使用 `font-weight: bold` / `700`。 + +自定义字体的 PostScript name 映射: + +| PostScript name | CSS 写法 | 备注 | +| --- | --- | --- | +| `xx-Regular` | `font-family: xx;` | 默认值可不加后缀 | +| `xx-Medium` | `font-family: xx; font-weight: bold;` | | +| `xx-Semibold` | `font-family: xx; font-weight: bold;` | | +| `xx-Bold` | `font-family: xx; font-weight: bold;` | | + +### 伪元素 animation 不支持的处理 + +Skyline 下伪元素的 `animation` 不生效。 + +**替代方案一**:使用真实节点 + CSS animation + +```css +/* ❎ Bad — 伪元素 animation 在 Skyline 不生效 */ +.loading::after { + content: ''; + animation: spin 1s linear infinite; +} + +/* ✅ Good — 真实节点 animation */ +.loading-spinner { + animation: spin 1s linear infinite; +} +``` + +**替代方案二**:使用 worklet 动画 + +```js +const { shared, timing, Easing } = wx.worklet +``` + +详见 [Worklet 动画与手势系统参考](./skyline-worklet-animation.md)。 + +### 其他属性适配 + +| 不支持/受限属性 | 限制说明 | 替代方案 | +| --- | --- | --- | +| `box-shadow` 多层 | 不支持多个叠加 | 拆分为多节点或合并为单层 | +| `text-decoration` | 仅 text 节点生效 | view 内文字用 `` 包裹 | +| `text-overflow` | 仅 text 节点生效 | 同上 | +| `backdrop-filter` | 不支持 multi function / drop-shadow / url | 简化滤镜 | +| `filter` | 不支持 multi function / drop-shadow / url | 简化滤镜 | +| `border-radius` 非 0 | 四边 border-color / border-style 需一致 | 保持一致或拆分节点 | +| `animation-fill-mode` | 不支持 `none` / `backwards` | 注意默认表现为 `forwards` | +| inline-block margin | 不生效 | 使用 padding 替代(注意 padding-box 增大可能影响定位基准) | + +### 隐藏元素 + +- `display: none`:支持,注意 Skyline 默认值是 `flex` 不是 `block` +- `visibility: hidden`:支持 +- `opacity: 0`:支持 +- 避免使用 `display: none` 后又依赖默认 `block` 布局,显式声明 `display: block` + +## 组件适配 + +### 不支持组件的替代方案 + +| 组件 | 替代方案 | +| --- | --- | +| `web-view` | 建议承载 web-view 的页面单独配置 `"renderer": "webview"` | +| `movable-area` / `movable-view` | 手势组件 + worklet 动画方案替代 | +| `navigation-bar` | 自定义导航栏(`common-nav` 通用组件) | +| `editor` | 暂无替代方案 | +| `progress` | 自定义实现 | + +### scroll-view 行为差异 + +- **必须指定 `type` 属性**:`type="list"`(列表滚动)、`type="custom"`(自定义布局)、`type="nested"`(嵌套滚动) +- `show-scrollbar` / `enhanced` 等属性在 Skyline 下行为可能略有差异 +- 暂不支持自动撑开(8.0.54+ 可配置 `enableScrollViewAutoSize`) + +### 自定义组件样式隔离 + +Skyline 下自定义组件的样式隔离与 WebView 存在差异: + +**tag / id 选择器不支持跨自定义组件匹配** + +```css +/* ❌ Bad — Skyline 下无法跨组件匹配 */ +/* 父组件的样式 */ +child-component { color: red; } +#child-id { color: blue; } + +/* ✅ Good — 使用 class 选择器 + 样式隔离配置 */ +.child-component { color: red; } +``` + +**class 遵循组件样式隔离机制**:需注意 Skyline 下 tag 选择器遵循样式隔离机制(WebView 下不受样式隔离约束)。可通过 `tagNameStyleIsolation: "legacy"` 对齐 WebView 表现。 + +**宽高 100% 可能失效**:Skyline 下设置了 `defaultDisplayBlock` 后,组件的宽高 `100%` 可能失效,需手动设置宽高。 + +**root-portal 内样式选择器限制**:`root-portal` 会将节点移动到根节点下,外部选择器无法匹配内部节点。详见 [fixed 定位替代方案](#fixed-定位替代方案) 中的说明。 + +### 组件根节点表现异常 + +Skyline 下自定义组件根节点有以下默认行为: + +- 默认 `block` 布局 + `relative` 定位 +- 不支持 `inline` 布局 +- `position: relative` 会改变定位基准 +- 宽高 `100%` 可能失效 + +**处理方式**: + +- 手动设置显式宽高 +- 加 `skyline-root` 类处理定位 +- 自定义组件内用 `pointer-events: auto` 抵消 `skyline-root` 的 `pointer-events: none` + +## 常见问题与踩坑记录 + +以下问题来自生产环境 Skyline 适配的实际踩坑记录,按类别整理。 + +### glass-easel 适配注意 + +Skyline 使用 `glass-easel` 作为组件框架,与 WebView 下的旧组件框架存在行为差异。 + +**1. properties 默认值必须使用 `value` 而非 `default`** + +glass-easel 要求组件 properties 的默认值通过 `value` 字段声明,使用 `default` 字段会被忽略,导致属性值为 `undefined`。 + +```js +// ❎ Bad — glass-easel 下 default 无效 +Component({ + properties: { + title: { + type: String, + default: '' // 无效,属性值为 undefined + } + } +}) + +// ✅ Good — 使用 value 声明默认值 +Component({ + properties: { + title: { + type: String, + value: '' // glass-easel 下生效 + } + } +}) +``` + +**2. wx:for 使用 computed 属性需 initData 防护** + +当 `wx:for` 绑定的数据是 computed 计算属性时,组件初始化阶段 computed 尚未计算完成,`wx:for` 会收到 `undefined`,触发 `"for-list data is neither Array nor Object"` 错误。 + +```js +// ❎ Bad — computed 属性在初始化时可能为 undefined +Component({ + computed: { + list() { + return this.data.rawList.filter(item => item.active) + } + } +}) + +// ✅ Good — 提供 initData 默认值防护 +Component({ + data: { + rawList: [] + }, + initData: { + list: [] // 初始值防护,避免 wx:for 报错 + }, + computed: { + list() { + return this.data.rawList.filter(item => item.active) + } + } +}) +``` + +**3. properties type 校验报错** + +在 glass-easel 下,如果 properties 的 type 声明与实际传入值不匹配,会触发 `"xxx is not illegal"` 类型校验错误。两种解决方式: + +- 将 `type` 设为 `null`(跳过类型校验) +- 通过 `initData` 提供正确类型的初始值 + +```js +// 方式一:type 设为 null 跳过校验 +Component({ + properties: { + config: { + type: null, // 跳过类型校验 + value: {} + } + } +}) + +// 方式二:initData 提供正确类型 +Component({ + initData: { + config: {} + } +}) +``` + +**4. 异步组件样式乱序** + +基础库 3.0.0+ 中,异步组件(按需注入的组件)在 Skyline 下可能出现样式加载顺序与 WebView 不一致,导致样式覆盖关系异常。需测试异步加载组件的样式表现。 + +**5. 异步组件 attached 生命周期时序差异** + +Skyline 下异步组件的 `attached` 生命周期触发时机与 WebView 不同,可能在实际渲染完成前触发。依赖 DOM 布局信息的逻辑(如 `getBoundingClientRect`)应移至 `ready` 生命周期。 + +### 布局踩坑 + +**1. flex + column 导致 overflow:hidden 失效** + +在 Skyline 下,`display: flex; flex-direction: column` 的容器设置 `overflow: hidden` 可能失效,子节点仍会溢出显示。 + +```css +/* ❎ Bad — overflow:hidden 可能失效 */ +.container { + display: flex; + flex-direction: column; + overflow: hidden; +} + +/* ✅ Good — 显式约束子节点或使用 scroll-view */ +.container { + display: flex; + flex-direction: column; + overflow: hidden; + /* 确保子节点有 flex-shrink: 0 或明确高度约束 */ +} +.child { + flex-shrink: 0; +} +``` + +**2. inline-block 元素 margin 不生效** + +Skyline 不支持 inline-block 布局,即使在 text 组件内部使用了类似 inline-block 的布局方式,`margin` 也不生效,只能使用 `padding` 替代。注意 padding 会增大元素盒尺寸(默认 border-box),可能影响定位基准。 + +**3. margin 合并行为差异** + +WebView 中相邻块级元素的上下 margin 会合并(BFC 机制),Skyline 没有 BFC,margin 不会合并。这会导致 WebView 下视觉间距较小的元素在 Skyline 下间距翻倍。 + +```css +/* WebView 下两个 .item 间距为 20rpx(margin 合并) */ +/* Skyline 下间距为 40rpx(margin 不合并) */ +.item { + margin-bottom: 20rpx; +} + +/* ✅ Good — 使用 flex gap 替代 margin 避免合并差异 */ +.list { + display: flex; + flex-direction: column; + gap: 20rpx; +} +``` + +**4. fixed 节点页面转场时裁切异常** + +Skyline 页面转场过程中,使用 `transform: translateX(-100%)` 等方式隐藏的 fixed 节点(如侧边栏)可能在转场动画期间短暂可见。这是因为页面转场时 transform 作用域与 fixed-context 的交互与 WebView 不同。 + +处理方式:转场期间通过 `opacity: 0` 配合隐藏,或在转场完成后才设置 fixed 节点内容。 + +**5. image 组件 max-width 行为异常** + +Skyline 下 image 组件设置 `max-width` 后,实际渲染宽度可能与预期不符。建议使用明确的 `width` 值而非依赖 `max-width` 约束。 + +**6. image 组件不支持 border/padding** + +Skyline 下 image 组件设置 `border` 或 `padding` 会导致图片尺寸计算异常(图片被撑大)。需要边框或内边距效果时,用 view 包裹 image,在 view 上设置 border/padding: + +```html + + + + + + + +``` + +**7. z-index 实践分层方案** + +生产环境推荐的 z-index 分层方案(需配合 `root-portal` 使用): + +| 层级 | z-index 值 | 用途 | 示例 | +| --- | --- | --- | --- | +| Layer 100 | 100 | 全局模态弹窗 | privacy-dialog、common-dialog、common-toast | +| Layer 100 | 100 | 底部导航栏 | 底部 tab 导航 | +| Layer 10 | 10 | 业务弹窗 | auth-scene、资源弹窗、home-popup | +| Layer 0 | 0 / 不设置 | 正常文档流 | 页面内容 | +| Layer -1 | -1 | 需要置于底层的组件 | map 组件 | + +**原则**: +- 同一层级内的兄弟节点靠 DOM 顺序决定层叠 +- 跨层级通过 z-index 差值保证互不干扰 +- 所有需要全局层级的节点通过 `root-portal` 提升到根节点 + +### 样式踩坑 + +**1. animation API 不支持 → 使用 CSS transition** + +Skyline 不支持 `wx.createAnimation` API(`animation` 属性赋值方式),需要改用 CSS `transition` 或 worklet 动画。 + +```js +// ❎ Bad — wx.createAnimation 在 Skyline 下无效 +const animation = wx.createAnimation({ + duration: 300, + timingFunction: 'ease' +}) +this.setData({ animation: animation.opacity(0).step().export() }) + +// ✅ Good — 使用 CSS transition +``` + +```css +.fade-element { + transition: opacity 0.3s ease; +} +.fade-element.hidden { + opacity: 0; +} +``` + +**2. apng 不支持动画** + +Skyline 下 apng 格式图片不支持动画播放,只会显示第一帧。需要动画效果时使用 awebp 或 gif 格式替代。 + +**3. backdrop-filter 在 map 组件上不生效(iOS)** + +iOS 上 `backdrop-filter: blur()` 应用在 map 组件上时不生效。需使用原生导航栏或其他非 map 区域的模糊效果方案。 + +### 组件踩坑 + +**1. movable-area / movable-view 替代方案** + +Skyline 不支持 `movable-area` / `movable-view`,必须使用手势组件 + worklet 动画方案替代: + +```html + + + + 可拖拽内容 + + +``` + +详见 [Worklet 动画与手势系统参考](./skyline-worklet-animation.md)。 + +**2. picker-view 双列同时滚动问题** + +Skyline 下 `picker-view` 存在双列同时滚动时索引错乱的问题,特别是日期选择器切换日期后可能出现索引越界。建议: +- 使用 `picker` 组件替代(非自定义场景) +- 自定义实现时做好边界校验 + +**3. swiper 单项无限滚动与 item 宽度设置** + +Skyline 下 `swiper` 在单项无限循环时可能表现异常,`swiper-item` 设置自定义宽度可能不生效。建议: +- 避免单项无限循环场景 +- `swiper-item` 宽度通过内部节点控制而非直接设置 + +**4. map 组件 API 兼容** + +- `map.getScale()` 在 Skyline 下可能无响应,需通过 `bindregionchange` 事件获取缩放级别 +- Android 上 map 组件高度动态变化时可能出现渲染异常,建议固定高度或通过 `wx:if` 重新创建 + +**5. 键盘收起/恢复问题** + +Skyline 下 `input` / `textarea` 的键盘收起和恢复行为与 WebView 有差异,可能导致页面布局跳动。需额外测试键盘弹出/收起场景。 + +**6. scrollOffset 节点限制** + +Skyline 下 `scrollOffset` 相关字段(如 `scrollLeft` / `scrollTop`)仅在 `scroll-view` 和 `viewport` 节点上生效,不能在普通 view 上使用。 + +### 其他踩坑 + +**1. vConsole 内存泄漏** + +Skyline 下 vConsole 存在内存泄漏,长时间开启可能导致页面崩溃。**测试 Skyline 时务必关闭 vConsole**。 + +**2. redirectTo 跳转预加载 Skyline 页面退出异常** + +`wx.redirectTo` 跳转到已调用 `wx.preloadSkylineView` 预加载的页面后,退出操作可能异常。如遇到此问题,暂时移除 `preloadSkylineView` 调用。 + +**3. wx:for 绑定 undefined 数据崩溃** + +Skyline 对 `wx:for` 数据校验更严格,绑定 `undefined` 值会直接崩溃。需确保 `wx:for` 绑定的数据始终为数组或对象,并提供 `wx:key`: + +```html + + + + + +``` + +**4. wxs 跨包引用错误** + +当主包中没有 glass-easel 组件时,wxs 跨包引用可能报错。解决方案是在主包中添加一个空的 glass-easel 组件(声明 `componentFramework: 'glass-easel'`),确保 glass-easel 运行时被加载。 diff --git a/.agents/skills/mpx2skyline/references/skyline-style-reference.md b/.agents/skills/mpx2skyline/references/skyline-style-reference.md new file mode 100644 index 0000000000..d7bbf213ab --- /dev/null +++ b/.agents/skills/mpx2skyline/references/skyline-style-reference.md @@ -0,0 +1,295 @@ +# Skyline WXSS 样式能力参考 + +## 目录 + +- [选择器支持](#选择器支持) +- [布局模块支持](#布局模块支持) +- [样式属性支持详情](#样式属性支持详情) + - [布局属性](#布局属性) + - [定位与层级](#定位与层级) + - [尺寸与溢出](#尺寸与溢出) + - [间距](#间距) + - [边框](#边框) + - [背景](#背景) + - [文本与字体](#文本与字体) + - [变换](#变换) + - [阴影与不透明度](#阴影与不透明度) + - [动画与过渡](#动画与过渡) + - [滤镜与遮罩](#滤镜与遮罩) + - [其他属性](#其他属性) + - [不支持的属性](#不支持的属性) +- [单位与类型支持](#单位与类型支持) +- [与 WebView 模式的关键样式差异汇总](#与-webview-模式的关键样式差异汇总) + +--- + +## 选择器支持 + +| 类别 | 示例 | 支持度 | 最低版本要求 | 备注 | +| --- | --- | --- | --- | --- | +| 通配选择器 | `* {}` | × | | | +| 元素选择器 | `tag {}` | ✓ | | | +| 类选择器 | `.class {}` | ✓ | | | +| ID 选择器 | `#id {}` | ✓ | | | +| 分组选择器 | `a, b {}` | ✓ | | | +| 直接子代选择器 | `a > b {}` | ✓ | | | +| 后代选择器 | `a b {}` | ✓ | | | +| 属性选择器 | `[attr] {}` | × | | | +| 一般兄弟选择器 | `a ~ b {}` | ✓ | 8.0.49 | | +| 紧邻兄弟选择器 | `a + b {}` | ✓ | 8.0.49 | | +| 伪类 :active | `:active {}` | ✓ | | | +| 伪类 :first-child / :last-child | | ✓ | | | +| 伪类 :not / :only-child / :empty | | ✓ | 8.0.49 | | +| 伪类 :nth-child | | ✓ | 8.0.50 | 对应 Skyline 1.3.3 | +| 伪元素 | `::before {}` / `::after {}` | ✓ | | **仅此两种,必须双冒号声明** | + +## 布局模块支持 + +| 模块 | 支持情况 | 备注 | +| --- | --- | --- | +| CSS Animation | ✓ | 安卓 8.0.37,iOS 8.0.39 | +| 背景与边框 | ✓ | 常用的基本支持 | +| 盒子模型 | ✓ | 支持 `border-box` 和 `content-box`,**没有 BFC** | +| Inline 布局 | × | 开发中 | +| Inline-Block 布局 | × | 仅支持在 text 组件里的嵌套结构使用,完整版本开发中 | +| Block 布局 | ✓ | 需配置 `defaultDisplayBlock` 开启,默认为 flex | +| Flex 布局 | ✓ | 包括 inline-flex 布局 | +| 字体 | ✓ | 基本支持,也支持自定义字体 | +| Positioned 布局 | ✓ | `sticky` 可使用 `sticky-header`/`sticky-section` 替代 | +| CSS Transition | ✓ | | +| CSS Variable | ✓ | 安卓 8.0.35,iOS 8.0.38 | +| Media queries | ✓ | 只支持 DarkMode | +| Font-face | ✓ | 只支持 ttf 格式 | + +## 样式属性支持详情 + +### 布局属性 + +| 属性 | 支持格式 | 默认值 | 备注 | +| --- | --- | --- | --- | +| `display` | `none` / `flex` / `block` | **`flex`** | **默认值与 WebView 不同**(WebView 为 `block`);可通过配置 `defaultDisplayBlock` 改为 `block` | +| `flex-direction` | `row` / `row-reverse` / `column` / `column-reverse` | `column` | | +| `flex-wrap` | `nowrap` / `wrap` / `wrap-reverse` | `nowrap` | | +| `flex-grow` | `` | `0` | | +| `flex-shrink` | `` | `1` | | +| `flex-basis` | `` / `auto` | `auto` | | +| `order` | `` | `0` | | +| `gap` | `` | `0` | | +| `flex` | 简写 | | 支持解析但以展开属性为准 | +| `align-items` | `stretch` / `center` / `flex-start` / `flex-end` / `baseline` | `stretch` | | +| `align-self` | `auto` / `stretch` / `center` / `flex-start` / `flex-end` / `baseline` | `auto` | | +| `align-content` | `stretch` / `center` / `flex-start` / `flex-end` / `space-between` / `space-around` | `auto` | | +| `justify-content` | `center` / `flex-start` / `flex-end` / `space-between` / `space-around` / `space-evenly` | `flex-start` | | + +### 定位与层级 + +| 属性 | 支持格式 | 默认值 | 备注 | +| --- | --- | --- | --- | +| `position` | `relative` / `absolute` / `fixed` | `relative` | `fixed` 在 8.0.43 开始支持,**不支持 `top`/`left`/`bottom`/`right` 默认值 `auto` 解析**;`sticky` 使用 `sticky-header`/`sticky-section` 替代 | +| `z-index` | `` | `0` | **仅兄弟节点生效,无层叠上下文机制**;不支持在 scroll-view 下的直接子节点上应用 | +| `left` / `right` / `top` / `bottom` | `` | `auto` | `fixed` 定位时不支持默认值 `auto` 解析 | +| `overflow` | `hidden` / `visible` | `visible` | **不支持 `scroll`**,只能通过 scroll-view 实现;**不支持单独设置 `overflow-x`/`overflow-y`** | +| `pointer-events` | `auto` / `none` | `auto` | | +| `visibility` | `visible` / `hidden` | `visible` | | + +### 尺寸与溢出 + +| 属性 | 支持格式 | 默认值 | 备注 | +| --- | --- | --- | --- | +| `width` / `height` | `` | `auto` | | +| `min-width` / `min-height` | `` | `auto` / `none` | | +| `max-width` / `max-height` | `` | `auto` | | +| `box-sizing` | `border-box` / `content-box` | **`border-box`** | **默认值与 WebView 不同**(WebView 为 `content-box`);可通过配置 `defaultContentBox` 改为 `content-box` | + +### 间距 + +| 属性 | 支持格式 | 默认值 | 备注 | +| --- | --- | --- | --- | +| `padding` / `padding-left` / `padding-top` / `padding-right` / `padding-bottom` | `{1,4}` | `0` | | +| `margin` / `margin-left` / `margin-top` / `margin-right` / `margin-bottom` | `{1,4}` | `0` | inline-block 元素 margin 不生效,只能用 padding | + +### 边框 + +| 属性 | 支持格式 | 默认值 | 备注 | +| --- | --- | --- | --- | +| `border-left-width` 等 | `` | `3` | | +| `border-left-style` 等 | `` | `none` | 支持 `none` / `hidden` / `solid` / `dashed` / `dotted` | +| `border-left-color` 等 | `` | `black` | **默认值与 WebView 不同**(WebView 为 `currentColor`) | +| `border-radius` / `border-top-left-radius` 等 | `{1,2}` | `0` | **`border-radius` 非 0 时,四边的 `border-color` 和 `border-style` 需一致**,`border-width` 可不一致 | +| `border` / `border-left` 等简写 | | | 支持解析但以展开属性为准 | + +### 背景 + +| 属性 | 支持格式 | 默认值 | 备注 | +| --- | --- | --- | --- | +| `background-color` | `` | `transparent` | | +| `background-image` | `none` / `` | `none` | **不支持多张图片** | +| `background-size` | `contain` / `cover` / `[\|auto]{1,2}` | `auto` | | +| `background-position` | 完整 `#` | `0 0` | 参考 MDN | +| `background-repeat` | `repeat-x` / `repeat-y` / `repeat` / `no-repeat` | `repeat` | | +| `background` 简写 | | | 支持解析但以展开属性为准 | + +### 文本与字体 + +| 属性 | 支持格式 | 默认值 | 备注 | +| --- | --- | --- | --- | +| `font-size` | `` | `16px` | **不支持百分比**;不支持 keyword (`smaller` 等) | +| `font-weight` | `normal` / `bold` / `` | `normal` | **部分机型不支持 500/600 数值**,需使用 `bold`/`700` | +| `font-family` | 通用字体族 / `` | | | +| `font-style` | `normal` / `italic` | `normal` | | +| `line-height` | `normal` / `` / `` / `` | `normal` | | +| `text-align` | `left` / `center` / `right` / `justify` / `start` / `end` | `start` | | +| `white-space` | `normal` / `nowrap` | `normal` | | +| `text-overflow` | `clip` / `ellipsis` | `clip` | **仅作用于 text 节点** | +| `word-break` | `normal` / `break-all` | `normal` | | +| `word-spacing` | `normal` / `` | `normal` | | +| `letter-spacing` | `normal` / `` | `normal` | | +| `text-decoration-line` | `none` / `underline` / `overline` / `line-through` | `none` | **仅作用于 text 节点** | +| `text-decoration-style` | `solid` / `double` / `dotted` / `dashed` / `wavy` | `solid` | **仅作用于 text 节点** | +| `text-decoration-color` | `` | `black` | **仅作用于 text 节点**;默认值与 WebView 不同(WebView 为 `currentColor`) | +| `text-decoration` 简写 | | | 支持解析但以展开属性为准;当前仅支持设置一种类型 | +| `text-shadow` | `none` / `? && {2,3}` | `none` | | + +### 变换 + +| 属性 | 支持格式 | 默认值 | 备注 | +| --- | --- | --- | --- | +| `transform` | `none` / `` | `none` | | +| `transform-origin` | `left` / `center` / `right` / `top` / `bottom` / `{1,2}` | `50% 50%` | | + +### 阴影与不透明度 + +| 属性 | 支持格式 | 默认值 | 备注 | +| --- | --- | --- | --- | +| `box-shadow` | `none` / `inset? && {2,4} && ?` | `none` | **不支持多个叠加** | +| `opacity` | `` | `1` | | +| `color` | `` | `black` | | + +### 动画与过渡 + +| 属性 | 支持格式 | 默认值 | 备注 | +| --- | --- | --- | --- | +| `transition-property` | `none` / `all` / `transform` / `opacity` 等 | `all` | 基本都支持 | +| `transition-duration` | `