Skip to content

Commit 8e1b521

Browse files
committed
Merge branch 'master' into feat-swiper-display-multi-and-changestart
2 parents 388d711 + b7dae95 commit 8e1b521

209 files changed

Lines changed: 13495 additions & 862 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/mpx2rn/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name: mpx2rn
33
description: Mpx 跨端输出 RN(简称 Mpx2RN 或 Mpx2DRN)的开发适配指南,覆盖模板、脚本、样式、JSON 配置四大维度。当用户进行 Mpx2RN 相关任务时强制调用,包括但不限于:技术方案设计、页面 / 组件的开发迭代、旧项目跨端适配改造、编译和运行时报错排查、Code Review 等。当用户问题不涉及 Mpx2RN 时不应调用,如 Mpx 小程序开发问题,RN 原生开发问题、Mpx2Web 相关问题等。
44
metadata:
5-
version: "2.10.24"
5+
version: "2.11.0"
66
author: donghongping
77
---
88

.agents/skills/mpx2rn/references/rn-script-reference.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@
184184
| `triggerEvent(name, detail?)` | 方法 | 组件 | 向父节点派发自定义事件。 |
185185
| `selectComponent(selector)` | 方法 | 共用 | 按选择器取第一个匹配实例。RN 不能像小程序一样按 selector 遍历视图树,须在模板目标节点声明 **空 wx:ref**,由编译期建立 **`#id` / `.class` 与节点**的映射后,本 API 才能按小程序写法解析。 |
186186
| `selectAllComponents(selector)` | 方法 | 共用 | 取全部匹配实例数组,**RN 侧与 `selectComponent` 相同**:依赖模板 **空 wx:ref** 与编译期 selector 映射,仅支持 **`#id` / `.class`**|
187-
| `createSelectorQuery()` | 方法 | 共用 | 在实例作用域内创建查询对象。后续 **`select(selector)`** 等链式调用在 RN 上同样依赖目标节点 **空 wx:ref**,通过编译映射将 `#id` / `.class` 落到真实视图,以兼容小程序用法|
187+
| `createSelectorQuery()` | 方法 | 共用 | 在实例作用域内创建查询对象。后续 **`select(selector)`** 等链式调用在 RN 上同样依赖目标节点 **空 wx:ref**,通过编译映射将 `#id` / `.class` 落到真实视图;命中非 virtualHost 自定义组件时,返回该组件实体 host 节点信息|
188188
| `createIntersectionObserver(options?)` | 方法 | 共用 | 在实例作用域内创建交叉观察。若相对某一节点观察且传入 **`#id` / `.class`**(如 `relativeTo` 等),RN 侧同样要求该节点模板已声明 **空 wx:ref** 并完成编译期映射,其余行为依赖 `@mpxjs/api-proxy` 的 RN 实现。 |
189189
| `$refs` | 属性 | 共用 | 模板 **`wx:ref="refName"`** 对应的懒解析访问器(如 `this.$refs.refName`);**空 wx:ref 不会注册具名 ref**,但与 selector 映射可并存——需按名取子实例时再写 **`wx:ref="refName"`**|
190190
| `$watch` | 方法 | 共用 | 动态创建对数据路径或表达式的侦听,返回用于停止侦听的函数,行为与选项式 `watch` 对齐。 |
@@ -200,7 +200,7 @@
200200

201201
#### 注意事项
202202

203-
- **`selectComponent``selectAllComponents``createSelectorQuery`(含 `select` 等链式入参)、`createIntersectionObserver``relativeTo` / `observe` 等涉及 selector 时)**在小程序中依赖视图层按 selector 查找节点,**RN 无同等原生能力**;须在**与 script 中 selector 对应**的节点上声明 **空 wx:ref**,可与 `id``class` 并存,由 **Mpx 编译期**根据 **`#id` / `.class` 建立映射**。若需 **`$refs` / `context.refs`** 按名访问,再使用 **`wx:ref="refName"`**。映射**仅支持 `#id``.class`**,不支持复合、后代等选择器;**未写 `wx:ref` 则无法解析**`createSelectorQuery` / `createIntersectionObserver` 的测量与交叉等行为仍以 `@mpxjs/api-proxy` 的 RN 实现为准。
203+
- **`selectComponent``selectAllComponents``createSelectorQuery`(含 `select` 等链式入参)、`createIntersectionObserver``relativeTo` / `observe` 等涉及 selector 时)**在小程序中依赖视图层按 selector 查找节点,**RN 无同等原生能力**;须在**与 script 中 selector 对应**的节点上声明 **空 wx:ref**,可与 `id``class` 并存,由 **Mpx 编译期**根据 **`#id` / `.class` 建立映射**。若需 **`$refs` / `context.refs`** 按名访问,再使用 **`wx:ref="refName"`**。映射**仅支持 `#id``.class`**,不支持复合、后代等选择器;**未写 `wx:ref` 则无法解析**`createSelectorQuery().select()` / `selectAll()` 命中基础节点时返回基础节点信息,命中非 virtualHost 自定义组件时返回该组件实体 host 节点信息;virtualHost 组件没有实体 host 节点,不支持按组件节点测量。`createIntersectionObserver` 的交叉行为仍以 `@mpxjs/api-proxy` 的 RN 实现为准。
204204

205205
**使用示例:**
206206

@@ -220,7 +220,7 @@
220220
this.selectComponent("#chip")
221221
this.selectAllComponents(".cell")
222222
this.createSelectorQuery()
223-
.select("#box")
223+
.select("#chip")
224224
.boundingClientRect()
225225
.exec((res) => {
226226
console.log(res)
@@ -702,6 +702,7 @@ Mpx.config.rnConfig = {
702702
onStateChange(state) {
703703
console.log("navigation state", state)
704704
},
705+
disablePageTransition: true,
705706
openTypeHandler: {
706707
onShareAppMessage(shareInfo) {
707708
console.log("share", shareInfo)
@@ -718,11 +719,11 @@ Mpx.config.rnConfig = {
718719
| `projectName` | 由构建注入到 RN 入口,与 `AppRegistry.registerComponent` 相关(偏构建侧)。 |
719720
| `parseAppProps` | `(props) => { initialRouteName?, initialParams? }`,解析外层传入 App 根组件的初始路由。 |
720721
| `onStateChange` | 导航 state 变化时回调。 |
722+
| `disablePageTransition` |`true` 时禁用 RN 页面转场动画,框架内部映射为 `animation: "none"`|
721723
| `disableAppStateListener` |`true` 时不注册 `AppState` 监听(避免与宿主 App 重复)。 |
722724
| `openTypeHandler` | 对象,注册 `button` 组件在 RN 上 `open-type` 的容器侧实现,未注册对应键时点击会告警。 |
723725
| `openTypeHandler.onShareAppMessage` | 对应模板中 `open-type="share"`:框架会先取当前页 `onShareAppMessage` 的返回(含与默认 `title` / `path` 的合并及可选 `promise` 异步结果),再调用本回调,入参为 `{ title, path, imageUrl? }`,由宿主调起系统分享等能力。 |
724726
| `openTypeHandler.onUserInfo` | 对应模板中 `open-type="getUserInfo"`:由宿主实现获取用户信息的逻辑,结果需满足按钮侧对 `bindgetuserinfo` 的约定(以 `@mpxjs/webpack-plugin``mpx-button` 运行时为准)。 |
725-
| `statusBarTranslucent` | 影响 Stack `screenOptions` 中状态栏相关配置。 |
726727
| `getBottomVirtualHeight` | Android 底部虚拟区域高度修正。 |
727728
| `loadChunkAsync` | 异步分包加载实现。 |
728729
| `downloadChunkAsync` | 分包下载实现,用于实现 preloadRule。 |

.agents/skills/mpx2rn/references/rn-style-practice.md

Lines changed: 132 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
- [谨慎使用 font-weight 数值](#谨慎使用-font-weight-数值)
1616
- [布局最佳实践](#布局最佳实践)
1717
- [使用 Flexbox 布局](#使用-flexbox-布局)
18+
- [嵌套 fixed 定位](#嵌套-fixed-定位)
1819
- [不要依赖 BFC 和 margin 合并](#不要依赖-bfc-和-margin-合并)
1920
- [避免使用 Grid 布局](#避免使用-grid-布局)
2021
- [避免使用 Float 布局](#避免使用-float-布局)
2122
- [文本溢出处理](#文本溢出处理)
23+
- [混排文本 line-height 对齐](#混排文本-line-height-对齐)
2224
- [隐藏元素](#隐藏元素)
2325
- [文本垂直居中](#文本垂直居中)
2426
- [渐变中避免使用 transparent](#渐变中避免使用-transparent)
@@ -478,13 +480,14 @@ px 和 rpx 在 RN 与小程序平台都具备良好兼容性,建议优先使
478480
479481
**⚠️ 需要辅助属性的场景:**
480482
481-
1. **`font-size` 的百分比**需要传递 `parent-font-size` 辅助属性
482-
2. **`calc()` 中出现的任何百分比**都需要传递相应的 `parent-width` / `parent-height` 辅助属性(`calc()` 是框架模拟支持的特性)
483+
1. **`calc()` 中出现的任何百分比**都需要传递相应的 `parent-width` / `parent-height` 辅助属性(`calc()` 是框架模拟支持的特性)
483484
484485
```html
485486
<template>
486-
<!-- 场景1:font-size 百分比需要 parent-font-size -->
487-
<view parent-font-size="{{16}}" class="text" />
487+
<!-- 场景1:优先通过文本样式继承提供 font-size 百分比基准 -->
488+
<view class="text-parent">
489+
<text class="text">文本</text>
490+
</view>
488491
489492
<!-- 场景2:仅在无法替代时,calc() 中的百分比需要父级布局宽高辅助计算 -->
490493
<view id="calc-parent" class="calc-parent" wx:ref>
@@ -524,7 +527,16 @@ export default {
524527
525528
<style>
526529
.text {
527-
font-size: 120%; /* 需要 parent-font-size */
530+
font-size: 120%; /* 优先基于继承字号;无继承字号时按默认字号 16 计算 */
531+
line-height: 150%; /* 按最终 text 节点合并后的 font-size 计算 */
532+
}
533+
534+
.text-large {
535+
font-size: 160%; /* 与 .text 继承相同 line-height 时,会得到更大的最终行高 */
536+
}
537+
538+
.text-parent {
539+
font-size: 16px;
528540
}
529541
530542
.calc-parent {
@@ -549,9 +561,8 @@ export default {
549561
550562
1. **优先使用 rpx**:对于固定尺寸,rpx 是最可靠的选择
551563
2. **放心使用百分比**:`width`, `height`, `padding`, `margin` 等属性的百分比由 RN 原生支持,可以放心使用
552-
3. **谨慎使用字体百分比**:`font-size` 的百分比需要 `parent-font-size` 辅助属性,建议使用 rpx 代替
553-
4. **谨慎使用 calc() 中的百分比**:该写法需要 `parent-width` / `parent-height` 辅助计算,通常还要查询父级布局并延迟展示,存在性能与体验开销;优先使用原生百分比、Flex、rpx / vw / vh 或固定尺寸替代
554-
5. **使用 vh/vw**:对于视口相关的尺寸,vh/vw 是更好的选择
564+
3. **谨慎使用 calc() 中的百分比**:该写法需要 `parent-width` / `parent-height` 辅助计算,通常还要查询父级布局并延迟展示,存在性能与体验开销;优先使用原生百分比、Flex、rpx / vw / vh 或固定尺寸替代
565+
4. **使用 vh/vw**:对于视口相关的尺寸,vh/vw 是更好的选择
555566
556567
### 1 像素边框(极细线)
557568
@@ -745,6 +756,62 @@ Flexbox 是跨平台最可靠的布局方式。
745756
</template>
746757
```
747758
759+
### 嵌套 fixed 定位
760+
761+
Mpx2RN 中 `position: fixed` 不是由 RN 原生定位直接承载,而是通过 portal 将 fixed 节点提升到 page root 下,再使用 `position: absolute` 模拟固定定位。因此模板中嵌套的 fixed 节点,在 RN 视图实现层会变成 page root 下的兄弟节点,无法继续保持原模板里的父子关系。
762+
763+
这会影响依赖父子关系的能力,常见问题包括:
764+
765+
1. **层级不再由父子关系兜底**:外层 fixed 声明了较高的 `z-index`,内层 fixed 未声明 `z-index` 时,RN 侧提升后的外层节点可能遮挡内层节点。
766+
2. **不要依赖事件冒泡穿透父级**:内层 fixed 已不再是外层 fixed 的真实子节点,依赖父子关系的事件冒泡、统一拦截或关闭逻辑可能与原平台表现不一致。
767+
768+
**❌ 避免:**内层 fixed 依赖外层 fixed 的层级上下文与事件冒泡。
769+
770+
```html
771+
<template>
772+
<view class="mask" bindtap="close">
773+
<view class="panel">
774+
<view class="toast" bindtap="handleToastTap">提示内容</view>
775+
</view>
776+
</view>
777+
</template>
778+
779+
<style>
780+
.mask {
781+
position: fixed;
782+
z-index: 1000;
783+
}
784+
785+
.toast {
786+
position: fixed;
787+
}
788+
</style>
789+
```
790+
791+
**✅ 推荐:**嵌套 fixed 需要覆盖外层 fixed 时,在内层显式声明更高的 `z-index`;事件逻辑上避免依赖从内层 fixed 冒泡到外层 fixed,可分别绑定明确的处理函数,或通过共享状态 / 自定义事件完成联动。
792+
793+
```html
794+
<template>
795+
<view class="mask" bindtap="closeMask">
796+
<view class="panel">
797+
<view class="toast" catchtap="handleToastTap">提示内容</view>
798+
</view>
799+
</view>
800+
</template>
801+
802+
<style>
803+
.mask {
804+
position: fixed;
805+
z-index: 1000;
806+
}
807+
808+
.toast {
809+
position: fixed;
810+
z-index: 1001;
811+
}
812+
</style>
813+
```
814+
748815
### 不要依赖 BFC 和 margin 合并
749816
750817
小程序 / Web 的普通块级布局中存在相邻块级元素垂直 `margin` 合并行为,常见现象包括:父子元素的垂直外边距可能合并、相邻兄弟元素的上下外边距可能取较大值而不是相加。BFC(块级格式化上下文)是常见的隔离手段;例如 `overflow: hidden` 可通过创建 BFC 隔离部分父子 margin 合并。CSS margin 合并只发生在块级布局的垂直方向,水平方向的 `margin-left` / `margin-right` 不会发生 margin 合并。
@@ -1016,6 +1083,63 @@ Grid 布局在 RN 平台不支持。
10161083
10171084
---
10181085
1086+
## 混排文本 line-height 对齐
1087+
1088+
W3C 行内排版中,同一行内混排不同字号文字时,整行高度会按该行中最大的 `line-height` 计算;RN 原生文本排版会以首个子 `Text` 元素的 `lineHeight` 作为整行行高基准。典型问题是价格、单位、标签等混排场景里,小字号文字排在大字号前面时,首个子 `text` 继承父级的小字号行高,RN 会按该行高计算整行高度,导致后面的大字号片段被较小行高约束。
1089+
1090+
Mpx2RN 在文本样式继承与 `line-height` 计算口径上对齐 W3C,但 RN 在嵌套 `Text` 混排场景中的实际行盒渲染行为与 W3C 不一致,不会按同一行内最大的 `line-height` 撑开整行。因此处理同一行多字号混排时,不要让内外层分别维护多套行高;应取消内层片段的所有 `line-height` 设置,只在承载整行文本流的外层 `text` 上显式声明整行期望行高,取该行各片段中的最大行高。
1091+
1092+
**❌ 避免:**在内层不同字号片段上分别声明 `line-height`。这种写法把整行行高拆散到多个片段上,首个子 `text` 会继承父级小字号行高,RN 会以首个子 `Text` 的行高排版整行,也会让后续维护者误以为内层最大行高会自动影响外层。
1093+
1094+
```html
1095+
<template>
1096+
<text class="price-line">
1097+
<text>到手价 </text>
1098+
<text class="price-amount">99</text>
1099+
<text> 元</text>
1100+
</text>
1101+
</template>
1102+
1103+
<style>
1104+
.price-line {
1105+
font-size: 24rpx;
1106+
line-height: 32rpx; /* 首个子 text 继承父行高,RN 整行以 32rpx 为准 */
1107+
}
1108+
1109+
.price-amount {
1110+
font-size: 48rpx;
1111+
line-height: 56rpx; /* 该大行高不会撑开整行,RN 仍以首个子 text 继承到的 32rpx 为准 */
1112+
}
1113+
</style>
1114+
```
1115+
1116+
**✅ 推荐:**外层 `text` 承载同一行文本流,并显式声明整行期望行高;内层 `text` 只声明自身字号等片段样式,不再设置 `line-height`。下例中整行最大行高按大字号片段取 `56rpx`,因此只在外层 `.price-line` 声明 `line-height: 56rpx`。
1117+
1118+
```html
1119+
<template>
1120+
<text class="price-line">
1121+
<text>到手价 </text>
1122+
<text class="price-amount">99</text>
1123+
<text> 元</text>
1124+
</text>
1125+
</template>
1126+
1127+
<style>
1128+
.price-line {
1129+
font-size: 24rpx;
1130+
line-height: 56rpx;
1131+
}
1132+
1133+
.price-amount {
1134+
font-size: 48rpx;
1135+
}
1136+
</style>
1137+
```
1138+
1139+
如果原样式中内层使用百分比或 unit-less 倍率表达相对行高,迁移到混排场景时先换算出整行需要的最大行高,再统一写到外层。不要在内层继续保留相对 `line-height`,避免 RN 按片段各自字号计算出多套行高。
1140+
1141+
---
1142+
10191143
## 隐藏元素
10201144
10211145
**❌ 避免:**

0 commit comments

Comments
 (0)