Ahri-珊
目前接触的小程序开发使用的wepy框架,有很多坑点,所以调研下taro框架,做个对比。
功能对比
wepy:
类Vue开发风格
支持自定义组件开发
支持引入NPM包
支持Promise
支持ES2015+特性,如Async Functions
支持多种编译器,Less/Sass/Stylus/PostCSS、Babel/Typescript、Pug
支持多种插件处理,文件压缩,图片压缩,内容替换等
支持 Sourcemap,ESLint等
小程序细节优化,如请求列队,事件优化等
taro:
支持使用 npm/yarn 安装管理第三方依赖。
支持使用 ES7/ES8 甚至更加新的 ES 规范,一切都可自行配置。
支持使用 CSS 预编译器,例如 Sass 等。
支持使用 Redux 进行状态管理。
小程序 API 优化,异步 API Promise 化。
支持多端开发转化(这个很坑,基本可忽略)。
代码风格对比
针对开发体验来说,taro非常利于习惯React编程的人。除了不支持refs,基本和react写法一致,代码检查也很给力。wepy的语法我是使用起来不太习惯,容易犯一些低级语法错误,也很难检查出来。当然啦,如果你非常习惯于wepy语法,这些就都不是问题了。
为了更好的对比,我用两个版本的语言写了一个音频播放卡片页。
在实现这个音频播放卡片页的时候,发现wepy的一个问题: 页面销毁时,需要手动重置播放器状态,否则下次进入时还停留在上次的状态
,taro无这问题。
以下例子变量: playing
- 变化的class(对npm库的支持)
wepy(使用classnames需要写到computed里,这里就不使用了):
<view :class="{playing ? 'controller transition' : playing}" />
taro(可直接使用classnames):
<View
className={classnames({
'controller': true,
'transition': playing,
})}
/>
- 条件渲染
wepy:
<text wx:if="">0:00</text>
<image
wx:else
src="../assets/images/play.png"
/>
taro:
{
playing ?<text>0:00</text> : <image src="../assets/images/play.png" />
}
- 函数调用
wepy(需要包裹在methods中):
methods = {
audioPlay() {
if (this.playing) {
this.audioCtx.pause()
this.playing = false
} else {
this.audioCtx.play()
this.playing = true
}
}
}
<view @tap="audioPlay" />
taro:
audioPlay = () => {
if (this.state.playing) {
this.audioCtx.pause()
} else {
this.audioCtx.play()
}
this.setState({
playing: !this.state.playing,
});
}
<View onClick={this.audioPlay} />
-taro 与React写法的不同
1.属性不能传入 JSX 元素
const element = <Content footer={<View />} />
2.自定义组件的名称必须和引入时一致
比如按如下写法写了个component,在React中是可以直接 import XXX from ‘path’,但在taro中只能import ChildSecond from ‘path’,import错误会提示XXX未找到。
export default class ChildSecond extends Component {
render() {
return (
<View>balabala</View>
)
}
}
针对wepy开发痛点比较
组件的循环渲染
此处使用picker-view实现日期选择器为例。
wepy(使用辅助标签
问题:设置初始化value值不成功
解决方法2:在computed里计算value的值
<picker-view
value=""
>
<picker-view-column>
<repeat
for=""
key=""
>
<view>年</view>
</repeat>
</picker-view-column>
<picker-view-column>
<repeat
for=""
key=""
>
<view>月</view>
</repeat>
</picker-view-column>
<picker-view-column>
<repeat
for=""
key=""
>
<view>日</view>
</repeat>
</picker-view-column>
</picker-view>
taro( map 方法):
问题:PickerViewColumn未定义, pr
<View>
<View>{this.state.year}年{this.state.month}月{this.state.day}日</View>
<PickerView value={this.state.value} onChange={this.onChange}>
<PickerViewColumn>
{this.state.years.map(item => {
return (
<View>{item}年</View>
);
})}
</PickerViewColumn>
<PickerViewColumn>
{this.state.months.map(item => {
return (
<View>{item}月</View>
);
})}
</PickerViewColumn>
<PickerViewColumn>
{this.state.days.map(item => {
return (
<View>{item}日</View>
);
})}
</PickerViewColumn>
</PickerView>
</View>
非页面级组件生命周期
taro:
componentWillMount componentDidMount
wepy: onLoad
跨组件事件触发
wepy:
taro:
与react中跨组件事件触发相同,也可以使用this.$parent乱拿数据,乱调父组件函数- -。
问题:
1.不支持 onClick={() => this.changeText(‘balabala’)}这种写法,只能使用bind(箭头函数的语法是支持的,但是这样写就是没用,原因不详
2.组件内同一个函数不能bind两次,issue
Comments