1.Taro是什么
官方简介(3.x) Taro 是一个开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发 微信 / 京东 / 百度 / 支付宝 / 字节跳动 / QQ 小程序 / H5 等应用。现如今市面上端的形态多种多样,Web、React Native、微信小程序等各种端大行其道,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要。
2.为什么使用Taro
我接触Taro完全是出于工作安排?♂️,没有困难的工作,只有勇敢的打工人.我在阅读文档的间隙也在思考为什么要用Taro?
首先我们构思一个场景,某天电脑前的你正在搜索颈椎病康复指南,A经理找你说他想做一个Z产品微信小程序,因为你有微信小程序开发经验,所以很快你完成了工作任务准备继续搜索.A经理又来找你说他想要一个一摸一样的支付宝小程序,但是他并不要求性能多好,只是为了引流推广,他问你反正微信都做出来了这个也不难吧.你开始犯难了,你知道以后还有百度小程序、等等小程序等着你,这个时候假如你有Taro简直就是哆啦A梦的思维口袋,只要是A想要啥你就掏啥.目前这种跨小程序框架有uni-app、mpvue等等.
3.为什么要去做优化
关于Taro如何使用请参考Taro官方文档,非常的详细非常的方便,我觉得这次优化不仅仅是局限于Taro,即使以后不用Taro也许也能用到类似的思路呢.
下面说一下问题,Taro作为一个跨平台解决方案肯定会存在不同端有些方法或者业务逻辑不同,Taro提供了process.env.TARO_ENV
环境变量来供用户区分平台,所以在我们代码里就会存在下面逻辑
componentDidMount() {
if (process.env.TARO_ENV === 'weapp') {
//TODO 微信小程序逻辑
}
if (process.env.TARO_ENV === 'swan') {
//TODO 百度小程序逻辑
}
if (process.env.TARO_ENV === 'alipay') {
//TODO 支付宝小程序逻辑
}
}
-
充斥着逻辑判断的代码,影响代码的可维护性,特别对于我这种刚接触想了解每个平台有那些特殊性看着不清晰
-
如果没有Tree-shaking这些代码都会被打包
4.优化思路
Taro为了解决这种问题,支持统一接口的多端文件,来解决跨端差异的功能。如果多个端之间都有差异,那么开发者可以通过将文件修改成 原文件名 + 端类型 的命名形式,不同端的文件代码对外保持统一接口,而引用的时候仍然是 import 原文件名的文件,Taro 在编译时,会跟根据需要编译平台类型,将加载的文件变更为带有对应端类型文件名的文件,从而达到不同的端加载对应文件的目的。
如图所示,执行构建例如 taro build --type weapp
时,会根据type来决定加载的文件,这样我们就能根据不同文件提供方法来决定执行逻辑.比如每个文件提供一个handleComponentDidMount方法
import { handleComponentDidMount } from app.js
...
componentDidMount(){
handleComponentDidMount()
}
...
但是这样会有问题,首先每个方法都需要import
,当你在新建一个app.qq.js
时还要提供所有的方法,不符合优化结果.我更想要一种Vue minxin模式,只提供我想使用的方法,然后混入到App.js中,只关心自己平台需要做哪些事情.那继续想怎么混入?
我们目前项目使用Taro 2.x
,组件都是通过class来创建的,所以我们混入的是原型,原型的话可以通过继承来混入,注意点就是每个子类方法都要判断一下父类是否存在
class subClass extends superClass{
foo {
//TODO
if(super.foo) super.foo
}
}
继续这个思路,如何能在保持原有写法上更好的混入这些方法,既然是class的话,何不尝试一下装饰器(Decorator),如果还没用过装饰器大概介绍一下
@testable
class MyTestableClass {
// ...
}
function testable(target) {
target.isTestable = true;
}
MyTestableClass.isTestable // true
5.代码实现
app.js
import { mixinsApp } from './app'
@mixinsApp
class App extends Component {
}
./app/app.weapp.js(微信小程序)
import mixins from '@/utils/mixins'
export const mixinsApp = mixins({
componentDidMount() {
this.getSystemInfo()
},
getSystemInfo(){
//TODO
}
})
mixins.js
const LIFECYCLE_HOOKS = ['componentWillMount', 'componentDidMount', 'componentDidShow', 'componentDidHide']
/**
* 混入class中方法
* @param { Object } options 混入的属性
* @returns 返回一个接收混入对象的类
*/
export default options => {
return superClass => {
if (isEmpty(options)) {
return superClass
}
class subclass extends superClass {}
for (const key in options) {
Reflect.set(subclass.prototype, key, function(...arg) {
const res = []
res.push(options[key])
if (LIFECYCLE_HOOKS.includes(key) && Reflect.has(superClass.prototype, key)) {
res.push(superClass.prototype[key])
}
res.forEach(_ => _.apply(this, arg))
})
}
return subclass
}
}
目前问题就是觉得mixins混入一个Object对象有点反写法,里面最好应该是个class,这样调用方法时才能看起来没那么奇怪,不过只是mixins.js做下修改,不过我想两种都支持.
6.后记
以上就是我本次优化的思路想法,如果有什么可能更好的地方欢迎指出,我也不确定自己写的能用在项目上否,毕竟刚刚入职一周?,但是我就是觉得算是给自己一种思路,万一以后有用呢,也勉励自己能坚持以这种方式记录自己工作总结.
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!