本片文章将从以下三个方面进行讲解:
- 背景
- 使用转换
- 注意事项
一、背景
之前一段时间,调研过跨平台开发一系列框架,最终筛选出uni-app这款可以适用多端的开源框架。一套代码可以同时生成ios,Android,H5,微信小程序,支付宝小程序,百度小程序等。拓展能力很强,封装了H5+,支持nvue,也支持原生Android,ios开发。可以将原有的移动应用和H5应用改成uni-app应用。基于此,恰好可以将我们之前早期的小程序项目,转化成基于vue.js的uni-app组件
这将带来很多优势:
- 更优的组件渲染更新性能
- 更强的拓展性、和可维护性
- 更快的打包速度、和更便捷的打包方式
- 一套代码多端适用
- ...
二、使用转换
使用官方推荐的HBuilderX, github地址:https://github.com/zhangdaren/miniprogram-to-uniapp。该插件十分强大,通过简单的脚本命令,直接将我本地的小程序原生项目,clone生成了一份vue.js的项目。
诸如: 小程序setData的兼容、小程序生命周期的兼容,小程序各种api的封装,几乎涵盖了所有的小程序原生api。
但是尽管如此,仍是有很多需要注意的点,在实际开发中需要我们注意的。
事先声明,以下需要关注的点,是本人在迁移自己的小程序项目中遇到的切实存在 的问题,如果有更好的解决方案,欢迎讨论。
三、注意事项【踩坑】
- 对于wx.setData的处理:
HBuilderX转换过来之后,会在app.js中加入setData的重写,但这个是通过vue中this.$set和this.$get来实现的,也就是说尽管小程序中的setData没有被转化成this.xxx =...的方式(vue的语法),但仍然可以生效。可是如果setData处于原来小程序组件的生命周期中如attached,这种生命周期会被转换为beforeMount 这时setData就会有报错,解决办法:(1)修改成this.xx = ...的方式 (2) 删除生命周期,因为vue中不支持attache等生命周期函数, 如果非要在组件挂载或者更新的时候将prop或其他变量存储到data中,可以尝试通过watch函数。 - 对于wx.selectComponent
经过反复测试,uni-app不会转化这个api,但是转成vue组件后,这个api将不在生效,需要替换成ref获取节点。
解决方案:这点可以使用ref替换,如果转换前微信组件的生命周期中,可以直接this.$refs.xxx.api()。如果转换前是在微信lifetimes中定义的生命周期,uni-app会转换成vue的生命周期,这时用ref不能直接调用组件的api需要加一层 .$vm, 既this.$refs.xxx.$vm.api() - 由于小程序的语法不强制要求wxml必须最外层是单节点。组件中<page></page>节点下如果存在多节点,转换后会多一层dom节点, 当然如果在wxml中有最外层的container的话就忽略这个问题。
- 原生小程序:
<page> 1 2 3 </page>
- 转换后
<page> <view> 1 2 3 </view> </page>
这在组件中会非常致命,会直接引起之前的样式如滚动条超出,高度的一些100%设置,会失效。导致样式错乱,要格外小心。
- 原生小程序:
- 事件绑定
(1)catchtap="true" 在小程序支持这种写法,可以理解为绑定一个空函数,转换之后变成@tap.stop="true" 这个在uni-app中会报错 需要改成 @tap.stop="emptyFunc".
(2)很多catch方法会被自动转换,如catchtap ----> @tap.stop 但是有些方法如catchtouchmove,这个方法不会转为@touchmove.stop,需要手动修改 。 - 转换过程部分函数名会被修改,如果小程序中定义了xxx,以""开头得函数名都会被修改名字,在调用的时候就找不到对应的函数了,以及vue内置得hide、show等方法名字会被修改成hideFun:
- data中引用类型的状态,以“_”开头的状态均无法通过this访问,都是undefined,需要手动更改状态变量的名称。
- 通过ref获取子组件的data,需要去掉data,如this.$ref.modal.data.name 需要换成 this.$ref.modal.name
- 有时我们想要父组件访问子组件的属性和方法,会将子组件的this作用域回调给父组件,这种方式在转化为uni-app后不会直接报错,但是无法获取到,进行下一步操作会报错。解决方案:在父组件直接使用ref。
- 一些写死的属性数据转换过来可能会变成 字符串,如showTitle="{{true}}"转换之后变成 showTitle="true" 这个时候如果子组件还当作boolean类型处理,就会报错。
- 奇怪的input:如果需要动态绑定input的value,并针对用户输入做一些必要的过滤,如不允许输入数字。 需要在用户输入的时候更改对应的value值,同时在input事件中要把经过js处理的value值return,这样才可以成功过滤input的value,否则不管如果用正则拦截,input输入框上都会输入啥显示啥。
- . vue组件中data中的数据this.xxx去获取,小程序转过来极少的时候是this.data.xxx需要手动更改一下,这个问题具体什么时候出现还不太明确,但是需要注意一下。
四、小程序组件
pages.json文件,这块和小程序不同,不需要再页面级json中配置
{
"pages": [
{
"path": "slide-view/slide-view",
"style": {
"navigationBarTitleText": "slide-view",
"usingComponents": {
"slide-view": "/wxcomponents/miniprogram-slide-view/index"
}
}
}
]
}
.vue:
<slide-view></slide-view>可直接使用
需要注意:
• 小程序组件需要放在项目特殊文件夹 wxcomponents(或 mycomponents、swancomponents)。HBuilderX 建立的工程 wxcomponents 文件夹在 项目根目录下。vue-cli 建立的工程 wxcomponents 文件夹在 src 目录下。可以在 vue.config.js 中自定义其他目录
• 小程序组件的性能,不如vue组件。使用小程序组件,需要自己手动setData,很难自动管理差量数据更新。而使用vue组件会自动diff更新差量数据。所以如无明显必要,建议使用vue组件而不是小程序组件。比如某些小程序ui组件,完全可以用更高性能的uni ui替代。
结论
ok,以上就是本人在项目转换迁移过程中遇到的问题。总体感受还是不错的,该说不说的,HBuilderX还是帮我们做了更大部分的事情,但仍需要我们针对各自的业务需求,做一些写法上的调整,做一切事物之前,需要头脑中有一个概念,“小程序中的代码在转换过程会被修改,小程序的实现逻辑,不具有普适性”。
0 个评论
要回复文章请先登录或注册