知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X(jué)表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷(xiāo)的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷(xiāo)工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
您當(dāng)前位置>首頁(yè) » 新聞資訊 » 小程序相關(guān) >
Taro 轉(zhuǎn)快應(yīng)用的那些事(三)
發(fā)表時(shí)間:2021-1-5
發(fā)布人:葵宇科技
瀏覽次數(shù):189
前言
Taro 組件的生命周期基本和 React 組件的生命周期完全相同,這也是為何 Taro 上手這么容易的原因。但它是如何將生命周期對(duì)應(yīng)的轉(zhuǎn)化到小程序,快應(yīng)用,H5 等其他端語(yǔ)言的生命周期上呢?而且它真的能夠完全覆蓋到其他端組件(或頁(yè)面)的所有生命周期嗎?
內(nèi)容大綱
- Taro 組件生命周期轉(zhuǎn)化的基本原理
- 如何在 Taro 中攔截快應(yīng)用原生的生命周期
- 全局的錯(cuò)誤監(jiān)控
Taro 組件生命周期轉(zhuǎn)化的基本原理
其實(shí)理解生命周期的實(shí)現(xiàn)原理,就知道這很簡(jiǎn)單。只是將 Taro 組件上暴露的方法(如 componentWillMount
、componentDidMount
、componentDidShow
等等),在對(duì)應(yīng)的原生生命周期方法函數(shù)中去執(zhí)行就完事了。話不多說(shuō),先看 Taro 中摘錄的代碼片段。
// taro-quickapp/dist/index.js
var componentConf = {
data: initData,
onInit: function onInit() {
/** 這部分刪除了 */
},
onReady: function onReady() {
if (!isPage) {
initComponent.apply(this, [ComponentClass, isPage])
}
var component = this.$component
if (!component.__mounted) {
component.__mounted = true
componentTrigger(component, 'componentDidMount')
}
},
onDestroy: function onDestroy() {
componentTrigger(this.$component, 'componentWillUnmount')
var component = this.$component
component.hooks.forEach(function (hook) {
if (isFunction(hook.cleanup)) {
hook.cleanup()
}
})
var events = component.$$renderPropsEvents
if (isArray$1(events)) {
events.forEach(function (e) {
return taro.eventCenter.off(e)
})
}
},
}
if (isPage) {
componentConf['onShow'] = function () {
componentTrigger(this.$component, 'componentDidShow')
}
componentConf['onHide'] = function () {
componentTrigger(this.$component, 'componentDidHide')
}
pageExtraFns.forEach(function (fn) {
if (componentInstance[fn] && typeof componentInstance[fn] === 'function') {
componentConf[fn] = function () {
var component = this.$component
if (component[fn] && typeof component[fn] === 'function') {
return component[fn].apply(component, arguments)
}
}
}
})
globalRef.componentPath = isPage
addLeadingSlash$1(isPage) &&
cacheDataSet(addLeadingSlash$1(isPage), ComponentClass)
}
bindStaticFns(componentConf, ComponentClass)
bindProperties(componentConf, ComponentClass, isPage)
ComponentClass['privateTaroEvent'] &&
bindEvents(componentConf, ComponentClass['privateTaroEvent'])
return componentConf
復(fù)制代碼
簡(jiǎn)單說(shuō)明:componentConf
可以理解為原生,也就是 componentConf['onShow']
就表示了快應(yīng)用中頁(yè)面的生命周期 onShow
。最后就變成了在快應(yīng)用 onShow
的時(shí)候執(zhí)行了 Taro componentDidShow
的方法,就這么簡(jiǎn)單。
如何在 Taro 中攔截快應(yīng)用原生的生命周期
上面已經(jīng)清晰了 Taro 轉(zhuǎn)快應(yīng)用的生命周期方式,但同時(shí)我們也發(fā)現(xiàn)了還有好些快應(yīng)用的生命周期(如 APP
的生命周期 onShow
、onHide
、onError
等等),Taro 并沒(méi)有支持到(原因可能是還沒(méi)有跟上快應(yīng)用的迭代變化,或者認(rèn)為我們就是不需要.)。雖然有些功能社區(qū)暫時(shí)還未支持,但是偏偏我們業(yè)務(wù)場(chǎng)景上就要用了,那我們也不是只能反饋社區(qū)后等社區(qū)結(jié)果的,我們完全也是可以自己封裝辦到的。
那我們就先分析下 Taro 編譯后的快應(yīng)用代碼,代碼路徑在 dist/quickapp/src/app.ux
。
// app.ux 底部
exports.default = require('./npm/@tarojs/taro-quickapp/index.js').default.createApp(_App);
_index2.default.initPxTransform({
"designWidth": 750,
"deviceRatio": {
"640": 1.17,
"750": 1,
"828": 0.905
}
});
script>
復(fù)制代碼
其實(shí)發(fā)現(xiàn)編譯后的源碼很好理解,exports.default
是原生快應(yīng)用語(yǔ)言要求導(dǎo)出的 JS 對(duì)象, 在這里導(dǎo)出的是 Taro createApp
方法執(zhí)行后返回的一個(gè)對(duì)象。那么假如我們對(duì)這個(gè)即將導(dǎo)出的對(duì)象做重新賦值,并添加上我們想要添加的原生生命周期方法,那么是不是就已經(jīng)達(dá)到了攔截原生生命周期的目的。
對(duì) Taro 底層做一定的修改
所有修改的代碼內(nèi)容如下:
// @tarojs/cli/src/mini/astProcess.ts
switch (type) {
case PARSE_AST_TYPE.ENTRY:
const pxTransformConfig = {
designWidth: projectConfig.designWidth || 750
}
if (projectConfig.hasOwnProperty(DEVICE_RATIO_NAME)) {
pxTransformConfig[DEVICE_RATIO_NAME] = projectConfig.deviceRatio
}
if (isQuickApp) {
if (!taroImportDefaultName) {
node.body.unshift(
template(`import Taro from '${taroMiniAppFrameworkPath}'`, babylonConfig as any)()
)
}
node.body.unshift(template(`var quickappLifecycle = global.quickappLifecycle || {};`, babylonConfig as any)()); // 硬核植入快應(yīng)用生命周期
node.body.push(template(`export default Object.assign(require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName}),quickappLifecycle)`, babylonConfig as any)())
} else {
node.body.push(template(`App(require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName}))`, babylonConfig as any)())
}
node.body.push(template(`Taro.initPxTransform(${JSON.stringify(pxTransformConfig)})`, babylonConfig as any)())
break
復(fù)制代碼
// app.quickapp.js
quickappLifecycle.onShow = () => {
// 業(yè)務(wù)代碼
}
quickappLifecycle.onHide = () => {
// 業(yè)務(wù)代碼
}
復(fù)制代碼
生成的代碼
// app.ux 底部
exports.default = Object.assign(require('./npm/@tarojs/taro-quickapp/index.js').default.createApp(_App), quickappLifecycle);
_index2.default.initPxTransform({
"designWidth": 750,
"deviceRatio": {
"640": 1.17,
"750": 1,
"828": 0.905
}
});
script>
復(fù)制代碼
重點(diǎn)說(shuō)明
:我們的目的只要做到最后我們編譯后生成的代碼中,exports.default
導(dǎo)出的 JS 對(duì)象,是被我們賦值了新的生命周期方法即可。
查看 Taro 源碼發(fā)現(xiàn)編譯后的代碼,是由其 @tarojs/cli/src/mini/astProcess.ts
文件生成的,而且他的生成模板都是固定的,那么就動(dòng)點(diǎn)小手腳,在模板頂部插入一個(gè)變量
node.body.unshift(template(`var quickappLifecycle = global.quickappLifecycle || {};`, babylonConfig as any)()); // 硬核植入快應(yīng)用生命周期
復(fù)制代碼
然后再在模板輸出的地方將變量合并到輸出模塊中
node.body.push(template(`export default Object.assign(require('${taroMiniAppFrameworkPath}').default.createApp(${exportVariableName}),quickappLifecycle)`, babylonConfig as any)())
復(fù)制代碼
那么對(duì)于開(kāi)發(fā)來(lái)說(shuō),只需要在業(yè)務(wù)代碼中,正常的將生命周期掛載到變量就好了
// app.quickapp.js
quickappLifecycle.onShow = () => {
// app顯示的業(yè)務(wù)代碼
}
quickappLifecycle.onHide = () => {
// app隱藏的業(yè)務(wù)代碼
}
復(fù)制代碼
以上的攔截都是比較粗暴的覆蓋形式,可以做更細(xì)的優(yōu)化就不展開(kāi)了,同時(shí)其他的頁(yè)面級(jí)別的生命周期攔截方式也是類似的,就不繼續(xù)展開(kāi)了。
全局的錯(cuò)誤監(jiān)控
以上我們已經(jīng)基本摸清了 Taro 的生命周期原理,那么就做一個(gè)簡(jiǎn)單的業(yè)務(wù)實(shí)踐。應(yīng)用的全局錯(cuò)誤監(jiān)控照道理是每一個(gè)應(yīng)用都應(yīng)該要有的,以下的代碼片段是我們分別對(duì)小程序和快應(yīng)用做的全局生命周期攔截。業(yè)務(wù)代碼沒(méi)有摘錄(小程序可以直接對(duì)接微信平臺(tái),快應(yīng)用可以對(duì)接輕粒子),建議將錯(cuò)誤日志對(duì)接到內(nèi)部的錯(cuò)誤日志平臺(tái)上,通過(guò)平臺(tái)可以做很多的數(shù)據(jù)分析,以及預(yù)警機(jī)制,從而來(lái)保障我們的應(yīng)用穩(wěn)定。
// app.quickapp.js
/** 錯(cuò)誤攔截捕獲 */
function catchError() {
if (process.env.TARO_ENV == 'weapp') {
// 小程序生命周期攔截
const _originApp = App
App = function (options) {
const _options = { ...options }
_options.onUnhandledRejection = (err) => {
console.error(err && (err.reason ? err.reason : err))
}
_options.onError = (err) => {
console.error(err)
}
return _originApp(_options)
}
}
if (process.env.TARO_ENV == 'quickapp') {
// 快應(yīng)用生命周期攔截
// 監(jiān)聽(tīng) promise 錯(cuò)誤
if (global.QuickApp) {
global.QuickApp.unhandledrejection = (index, stack, message) => {
try {
console.error({
stack,
message,
})
} catch (error) {
console.log('unhandledrejection', error)
}
}
} // 監(jiān)聽(tīng) onError
quickappLifecycle.onError = (err) => {
try {
console.log('onError', err)
} catch (error) {
console.log('onError', error)
}
}
}
}
try {
catchError()
} catch (error) {}
復(fù)制代碼
最后
摸清 Taro 生命周期實(shí)現(xiàn)原理后,Taro 轉(zhuǎn)快應(yīng)用的那些事兒就更明白了。
作者:beezend
來(lái)源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
相關(guān)案例查看更多
相關(guān)閱讀
- 正規(guī)網(wǎng)站建設(shè)公司
- APP
- 昆明網(wǎng)站開(kāi)發(fā)
- 網(wǎng)站建設(shè)快速優(yōu)化
- 云南建設(shè)廳網(wǎng)站首頁(yè)
- 網(wǎng)站建設(shè)開(kāi)發(fā)
- 網(wǎng)站建設(shè)報(bào)價(jià)
- 開(kāi)發(fā)制作小程序
- 云南網(wǎng)絡(luò)公司
- 排名
- 網(wǎng)站建設(shè)公司網(wǎng)站
- 云南網(wǎng)站建設(shè)高手
- 云南小程序商城
- vue開(kāi)發(fā)小程序
- 報(bào)廢車(chē)管理
- 云南小程序開(kāi)發(fā)推薦
- web教程
- 汽車(chē)報(bào)廢管理系統(tǒng)
- 網(wǎng)站建設(shè)電話
- 開(kāi)通微信小程序被騙
- 云南小程序公司
- 汽車(chē)報(bào)廢拆解管理系統(tǒng)
- 跳轉(zhuǎn)小程序
- 云南百度小程序
- asp網(wǎng)站
- 生成海報(bào)
- 網(wǎng)站建設(shè)價(jià)格
- 海南小程序制作公司
- 云南網(wǎng)站建設(shè)公司地址
- 小程序用戶登錄