Mpx 跨端输出 RN 样式开发指南
背景介绍
Mpx 是一个以微信小程序语法为基础、进行了类 Vue 语法拓展支持的跨端开发框架,支持将同一套代码输出到小程序(微信、支付宝、百度等)、Web 和 React Native 平台。尽管 Mpx 在编译时和运行时对样式能力进行了一定程度的跨平台抹平,但在输出 RN 时在样式能力支持上仍与小程序和 Web 平台存在较大差异,本文档详细描述了 Mpx 输出 RN 时的样式能力支持情况,以及跨平台开发时样式兼容的最佳实践。
Mpx 采用类 Vue 的单文件组件(SFC)格式 .mpx 进行组件与页面定义,详情查看:Mpx 单文件组件
知识库索引
| 知识库 | 说明 |
|---|---|
| Mpx 单文件组件 | 描述了 Mpx 单文件组件的基本结构与语法,并提供简单示例,开发 Mpx 单文件组件时读取 |
| 条件编译 | 描述了 Mpx 中包括模板、脚本、样式和配置等不同部分的条件编译语法,当跨端适配开发遇到兼容性问题需要分端处理时读取 |
| 跨端输出 RN 样式能力参考 | 描述了 Mpx 输出 RN 时详细的样式能力支持情况,当查询某项样式能力是否支持,遇到样式不生效、样式报错等问题时读取 |
| 跨端输出 RN 样式开发最佳实践 | 描述了 Mpx 输出 RN 时常用选择器和样式属性的跨端兼容方案和样式开发最佳实践,当进行已有组件跨端样式适配改造或新组件跨端样式开发时读取 |
跨端输出 RN 样式适配改造
当用户要求对已有 Mpx 组件进行跨端输出 RN 样式适配改造时,遵循以下流程与约束。
输入
基于小程序技术规范编写的 {name}.mpx 组件。
输出
以用户指示为准,若无特殊指示则默认在原文件 {name}.mpx 中进行修改。在输出修改后的代码时,应输出完整的组件代码,避免使用省略号,确保用户可以直接复制或应用修改。
约束指引
进行样式适配改造时需严格遵循以下约束指引:
- 选择器单类化(示例):禁止使用复合选择器(如
.list.item),必须转换为单类名等效实现(如.list-item),并确保同步修改<template>结构和<script>(如createSelectorQuery)中的对应引用。
- Bad Example:
<style>.list.item {color: red;} </style> - Good Example:
<style>.list-item {color: red;} </style>
- 模板样式类名动态绑定尽可能使用
wx:style和wx:class模版指令,尽量避免在style和class属性中使用{{}}插值表达式进行动态绑定。
- Bad Example:
<view class="item {{isActive? 'active': ''}}"> - Good Example:
<view class="item" wx:class="{{{active: isActive}}}">
- 对于存在跨端兼容方案的选择器和样式属性,读取跨端输出 RN 样式开发最佳实践,优先改造为跨端兼容方案,以便于后期维护。
- 选择器的跨端兼容方案:
- 复合选择器(后代/交集等)→ 等效单类选择器:参考 - 子元素伪类(:first-child /:last-child /:nth-child)→ 使用 wx:class + index 判断:参考 - 伪元素选择器(::before /::after)→ 使用真实节点替代:参考 - 点击态伪类(:active)→ 使用 hover-class/hover-stay-time:参考
- 样式属性的跨端兼容方案:
- 极细边框:原平台 1rpx,RN 使用 hairlineWidth 并通过条件编译切换:参考 - 单位兼容:rem/em → 使用 rpx:参考 - 字体粗细:避免数值型 font-weight,使用 normal/bold:参考 - 文本溢出:white-space/text-overflow → 原平台保留样式,RN 使用 numberOfLines 模板属性条件编译:参考 - 隐藏元素:避免 display: none,使用尺寸归零与 overflow: hidden 等组合样式:参考 - 布局属性:避免 grid/float,统一使用 Flex 布局:参考 参考
- 非必要时减少条件编译的使用,避免出现大面积连续的条件编译,因为这会严重破坏代码的可读性和后期维护性。
- **保留原始样式定义中的
/*use rpx*/和/*use px*/注释**,此类注释用于编译期间批量切换样式单位。
任务流程
- 选择器适配改造:
- 分析组件的
<style>部分,对于sass、less、stylus等支持嵌套选择器写法的预处理语言,先将原代码中所有的嵌套选择器写法展开铺平为传统的选择器写法,便于后续进行选择器的兼容性判断及适配改造。
- Bad Example (嵌套选择器未展开): .list {.item {color: red; &.active {color: blue;}}} - Good Example (嵌套选择器已展开铺平): .list.item {color: red;}.list.item.active {color: blue;}
- 读取 Mpx 跨端输出 RN 样式开发最佳实践 · 选择器使用建议,分析组件的
<style>部分,将 RN 平台不支持的选择器改造为跨端兼容的等效实现,并同步更新<template>和<script>中对应的类名引用。 - 对于无法进行跨端兼容等效实现的选择器,使用原平台条件编译对该选择器样式片段进行局部包裹,保留在原平台输出产物中,并添加
todo注释记录不兼容 RN 平台的详情。
- Good Example (局部条件编译): /* @mpx-if (__mpx_mode__ === 'wx' || __mpx_mode__ === 'ali' || __mpx_mode__ === 'web') */ /* todo: RN 不支持::-webkit-scrollbar 伪元素,仅在原平台保留 */.scroll-view::-webkit-scrollbar {display: none;} /* @mpx-endif */
- 样式属性适配改造:
- 读取 跨端输出 RN 样式能力支持详情,对
<style>、<template>和<script>中定义的样式属性进行分析,检查是否存在 RN 平台不支持的样式属性。 - 对于 RN 平台不支持的样式属性,读取 Mpx 跨端输出 RN 样式开发最佳实践,将其改造为跨端兼容的等效实现。
- 对于无法进行跨端兼容等效实现的样式属性,使用原平台条件编译对该样式属性进行局部包裹,保留在原平台输出产物中,并添加
todo注释记录不兼容 RN 平台的详情。
- Good Example (局部条件编译): .animation-box {/* @mpx-if (__mpx_mode__ === 'wx' || __mpx_mode__ === 'ali' || __mpx_mode__ === 'web') */ /* todo: RN 不支持 keyframes 动画,仅在原平台保留 */ animation: slideIn 0.5s ease-in-out; /* @mpx-endif */}
- 检查与确认:
- 检查确保
<style>中不存在任何嵌套选择器写法。 - 检查确保
<style>、<template>和<script>中所有存在跨端兼容方案的选择器和样式属性都已被改造为跨端兼容的等效实现。 - 检查确保
<style>、<template>和<script>中所有 RN 平台不支持的选择器和样式属性都已被原平台条件编译所包裹。 - 检查确保
<style>、<template>和<script>中不存在大面积的条件编译,所有添加的条件编译仅最小包裹不兼容的样式片段。 - 检查确保
<style>条件编译处理后产物中不存在空选择器(无样式内容的选择器)。