最近使用 taro 来开发扩平台的电商项目。首先兼容的是小程序,使用的工具是微信开发者工具,H5 和 RN 在以后兼容。现在使用的 taro 的版本是 2.0.7,在对 RN 的兼容上据说有很多问题。。。
先总结一下遇到过的几个问题。
1. 在 taro 1.3.9 的版本中, className 中 使用三元运算符
按照原来使用 vue 或 react 的习惯,会直接在模板中使用三元运算符去动态设置className,像这样:
<div v-bind:class="{ isActive ? 'active' : 'not-actice' }">是否选中</div>
或这样:
<div className={ index === this.state.currentIndex ? 'active' : 'not-active' }>是否选中</div>
当时如果在taro 中按照原来的习惯来写,你会发现不好使,你得到的不是你想要的 active
或 not-active
,而是会返回 true
或 false
。如下:
<View className={`${ isActive? 'active' : 'empty'} empty-tip`}>暂无数据</View>
在 1.3.9 中,编译后为:
<view class="false empty-tip">暂无数据</view>
原来解决这个问题比较快的方式是使用 一个变量去处理,也可以使用别的方式。
不过在 taro 2.0.7 的版本中已经修复,现在可以正常使用(我还一直以为没有好,还在使用变量写法,写这篇总结的时候才发现好了😭)。
2.0.7 的版本编译后为:
<view class="empty empty-tip">暂无数据</view>
2. 在页面中使用了 transform: skew() 之后,出现的各种神奇问题
先说一下使用的场景,在 tabbar 页面中,点击某个按钮,进入它下面的页面 A,然后在 A 页面中,结构和设置的样式如下所示:

一开始,在编辑器中的表现是只要设置了
skew
,不管是skew
,还是 skewX
,还是 skewY
,页面都会展示为 tabbar 的内容,但是 Wxml 的内容没有变化,还是 A 页面的内容。现在的表现时,skewX
设置为 90deg
或 270deg
的时候会出现这个问题,像 180deg
360deg
其他的时候可以正常展示页面内容,其它的数值没有问题,也可能有没有试到的数字,不过其他的 90 的倍数 或 45 的倍数没有这个问题(原来是不管什么数字都有这个问题,现在刷新了几次页面之后就没有再出现了😂)。看这个表现应该是 taro 页面处理的问题,但是为什么我才疏学浅,不知道,如果有知道的可以留言,谢谢。
3. page 页面使用 defaultProps ,defaultProps 失效
具体的问题描述可以看这个 issue,可以看我(yuminMorning这个用户)标注的俩个代码片段,一个是正确的实现,一个有问题的实现。虽然实现的是不严禁,但是导致这个问题出现的原因还是因为我尝试在 page 页面中设置 defaultProps,这个做法是不合理的。页面不是组件,按使用规范来说是不能设置 defaultProps 的,如果想要设置默认值,可以试试使用 state。
这个问题告诉我们,要想少遇到坑,就要规范使用三方框架,按照他们的游戏规则来才会少踩坑。
4. tabbar 页面,既想要 tabbar 的展示效果,有想要普通页面的展示效果,怎么弄
在电商项目中,有个比较特殊的页面:购物车页面。
这个页面既是 tabbar 中不可缺少的页面,也是在其他页面可以访问的页面。他特殊在 tabbar 页面,是没有返回的,而在其他页面进入购物车页面时,正常逻辑还是要返回原来的页面的。
但是在 taro 中,tabbar 的路由会清空路由记录中的其他页面信息,值保留当前的 tabbar 页面。我们如果在其他页面,比如商品详情页,进入了购物车页面,路由信息中就会清空上个页面的记录,只保留购物车的路由信息(可打印日志查看),这样即使在页面中添加一个返回按钮也是不起作用的。
解决方式有两种,一种是比较麻烦的,自己自定义 tabbar,自己处理路由,这个比较自由,tabbar 的样式也可以自己自由定义了。
另一种比较简单,一种比较取巧的方式。
taro 提供了一个 copy.patterns 的配置,他允许你只需要配置好 from
某个 src
下的页面,to
某个 dist
下的页面(也可以是 src
页面,建议 dist
),taro 在编译时,就会根据 from
的页面生成一个一模一样的 to
的页面,这个页面我们可以在 pages 中写入路径,然后就可以访问了。代码如下:
copy: {
patterns: [{
from: 'src/pages/cart',
to: 'src/pages/cart-info'
}]
},
config: Config = {
pages: [
...
'pages/cart/index',
'pages/cart-info/index',
...
],
...
}
看效果图(图比较大😭):


这个做法比较好的一点是代码量少,实现简单,tabbar 和 页面的交互完全是原生实现,也保证了一致性。
copy.patterns 具体的用法可以参考文档。
但是这个也有个缺陷,第一次编译时,会报错,在文件没有生成的时候就访问了,找不到文件。生成文件之后再编译就好了。
如果不想这么麻烦,可以自己实现 copyPatterns,示例代码如下:
// 需要依赖两个库用于处理文件
const fs = require('fs-extra');
const chokidar = require('chokidar');
const copyPatterns = [{
from: 'src/pages/cart',
to: 'src/pages/cart-page'
},
{
from: 'src/pages/mine',
to: 'src/pages/mine-page'
}];
for (let i = 0; i < copyPatterns.length; i++) {
let from = copyPatterns[i].from;
let to = copyPatterns[i].to;
fs.copySync(from, to);
chokidar
.watch(from, { ignored: /^\./, persistent: true, ignoreInitial: true })
.on('all', () => {
fs.copySync(from, to);
});
}
先记录到这里,后续遇到值得记录的问题会再补充。
本人博客地址:taro 踩坑 ing
网友评论