与 web 开发 的区别
1. 尽量避免使用组合选择器
- 原因:
- 组合选择器在
react-native
中是不受支持 - 组合选择器在 各小程序 中支持程度不一, 且在使用插槽的情况下无效(微信小程序的组件使用插槽机制,但是组件不在命名插槽之内)
- 特殊情况需要使用组合选择器的:
- 需要对
TaroUI
进行样式覆盖的。 如果是在所有地方样式一致,就可以使用全局样式覆盖的方式;但是如果某组件在不同位置具有不同的样式, 这时候就不得不借用组合选择器(有更好方案的可以联系我补充)。
2. 条件编译
- 按文件名进行条件编译
假设目录中存在这些文件
-- .
|- Picker.tsx
|- Picker.alipay.tsx
|- Picker.h5.tsx
则在引入 Picker 组件时,
import Picker from './Picker';
会自动引入特定平台的组件。
例如,在支付宝小程序编译时,会自动引用
Picker.alipay.tsx
文件, 在 h5 项目编译时使用Picker.h5.tsx
文件,而在其他环境编译时,则会回退到Picker.tsx
文件。
样式文件同样适用于这条规则。
- 按指令进行条件编译
指令编译类似于 C 语言
里面条件编译的宏,用法也基本一致。
- 指定平台保留
/* #ifdef %PLATFORM% */
.avatar {
width: 100px;
height: 100px;
}
/* #endif *
例如
/* #ifdef h5 alipay */
.avatar {
width: 100px;
height: 100px;
}
/* #endif *
以上代码只会在 h5 和 支付宝小程序 平台生效
- 指定平台剔除
/* #ifndef %PLATFORM% */
.avatar {
width: 100px;
height: 100px;
}
/* #endif *
例如
/* #ifndef rn alipay */
.avatar {
width: 100px;
height: 100px;
}
/* #endif *
以上代码不会在 react-native 和 支付宝小程序 平台生效。
注意 ifdef
和 ifndef
区别。
3. 样式限制
基本和 react-native
一致,原因是 react-native
布局引擎 yoga
的限制。
这里的原则是尽量以限制多的平台为准,实在差异较大的可以使用多平台多文件的方式。
4. 其它限制
-
不能使用
Array.prototype.map
之外的方法操作 JSX 数组这里官方文档有说明,是因为在小程序内部使用 wx:for 循环,所以不能使用其他方法。官方限制 如果真需要条件判断,需要先使用
Array.prototype.filter
筛选后在使用map
方法遍历。 -
props 声明。 在微信小程序端的自定义组件中,只有在
properties
中指定的属性,才能从父组件传入并接收。 由于使用和传递 props 的方法比较多样,包括直接使用,解构,解构赋值,跨层级传递等多种方法,建议组件设置defaultProps
,defaultProps
里面的属性都会设置到微信小程序的properties
里面。 -
父组件传入 jsx 的限制。在 react 里面我们可以通过传入一个渲染函数或 JSXElement,而在 taro 里面我们只能传入 JSXElement(而且必须是单元素)。而且传入的属性名必须以 render 开头。例如,
<Modal
renderHeader={<Header />}
renderFooter={<Footer />}
>
content
</Modal>
-
router state 的限制。taro 只支持通过 url search 的方式附加参数,不支持 router state。
-
setState
一定是异步的。官方说明 -
事件绑定传参。与 react 不同的是,这里使用
bind
比箭头函数
性能好。官方文档 -
this.props.children
无法操作,无法解构。任何对this.props.children
的操作都是非法的。看文档 -
ref 限制。使用 ref 拿到的感觉并不是组件实例,而是一堆属性的组合。使用 ref 应当谨慎。
5. 个人觉得不好的点
- jsx 使用单引号,常规 react 项目中一般使用双引号声明 jsx 属性。官方文档也没有说明具体原因。 github 上有人专为此提了一条工单,Taro 项目 jsx 无法格式化为双引号问题 #1239。官方有回复,但不说明是什么原因,我感觉可能是个 bug,但官方没有时间处理。