| | |
| | | * @author Tevin |
| | | */ |
| | | |
| | | import Taro, { getCurrentInstance, getCurrentPages } from '@tarojs/taro'; |
| | | import { $hostBoot } from '@components/bases/HostBoot'; |
| | | import project from '@project'; |
| | | |
| | | export class Pilot { |
| | | |
| | | constructor() { |
| | |
| | | methods: {}, |
| | | }; |
| | | const names = []; |
| | | let parent = null; |
| | | // 实例本身的字段 |
| | | Object.getOwnPropertyNames(this).forEach(name => names.push(name)); |
| | | // 类的字段 |
| | | Object.getOwnPropertyNames(Object.getPrototypeOf(this)).forEach(name => names.push(name)); |
| | | // 基类的字段,直到Pilot为止(不含Pilot) |
| | | parent = Object.getPrototypeOf(this); |
| | | while (parent instanceof Pilot) { |
| | | Object.getOwnPropertyNames(parent).forEach(name => names.push(name)); |
| | | parent = Object.getPrototypeOf(parent); |
| | | } |
| | | // 传递 |
| | | names.forEach(name => { |
| | | // 构造器忽略,如果存在属性 $methods 也忽略 |
| | |
| | | } |
| | | if (/^\$/.test(name)) { |
| | | if (name === '$data' && typeof dataAdd !== 'undefined') { |
| | | // 当有传data值进来,初始值必须带data中的字段 |
| | | const dataOrig = this.$data(); |
| | | // 转换 dataAdd 中 assets 属性下的图片地址值 |
| | | if (typeof dataAdd.assets !== 'undefined') { |
| | | dataAdd.assets = Pilot.transAssets(dataAdd.assets); |
| | | } |
| | | options.data = () => { |
| | | // 当有传data值进来,初始值必须带data中的字段 |
| | | const dataOrig = this.$data(); |
| | | return { |
| | | ...dataOrig, |
| | | ...dataAdd, |
| | | } |
| | | } |
| | | }; |
| | | }; |
| | | } else { |
| | | options[name.replace('$', '')] = this[name]; |
| | | } |
| | |
| | | options.methods[name] = this[name]; |
| | | } |
| | | }); |
| | | this._bindTaroPage(options); |
| | | return options; |
| | | } |
| | | |
| | | _bindTaroPage(options) { |
| | | // 绑定页面实例到Page |
| | | const { created, beforeDestroy, onMessage, onBridge } = options; |
| | | const option2 = { |
| | | created() { |
| | | const instance = getCurrentInstance(); |
| | | instance.page.$component = this; |
| | | // 绑定方法到页面实例 |
| | | this.$poster = Pilot.createPoster(this); |
| | | this.$onMessage = onMessage || (() => null); |
| | | this.$onBridge = onBridge || (() => null); |
| | | // 实际生命周期回调 |
| | | created && created.call(this); |
| | | }, |
| | | beforeDestroy() { |
| | | const instance = getCurrentInstance(); |
| | | delete instance.page.$component; |
| | | // 实际生命周期回调 |
| | | beforeDestroy && beforeDestroy.call(this); |
| | | // 取消绑定 |
| | | this.$onMessage = null; |
| | | this.$poster = null; |
| | | this.$onBridge = null; |
| | | }, |
| | | }; |
| | | options.created = option2.created; |
| | | options.beforeDestroy = option2.beforeDestroy; |
| | | delete options.onMessage; |
| | | delete options.poster; |
| | | delete options.onBridge; |
| | | } |
| | | |
| | | // 创建页面通讯器 |
| | | static createPoster($vm) { |
| | | return (pageType, action, data) => { |
| | | // 解除引用关系 |
| | | const nextData = JSON.parse(JSON.stringify(data || {})); |
| | | // 下一页 |
| | | if (pageType === 'nextPage') { |
| | | // 持续 3 秒,检测下一页是否存在 |
| | | let count = 0; |
| | | const timer = setInterval(() => { |
| | | if (++count > 60) { |
| | | clearInterval(timer); |
| | | } |
| | | const currentPages = getCurrentPages(); |
| | | const pageIndex = currentPages.findIndex(page => page.$component === $vm); |
| | | const nextPage = currentPages[pageIndex + 1]; |
| | | if (nextPage) { |
| | | clearInterval(timer); |
| | | nextPage.$component?.$onMessage(action, nextData); |
| | | } |
| | | }, 50); |
| | | } else if (pageType === 'prevPage') { |
| | | const currentPages = getCurrentPages(); |
| | | const pageIndex = currentPages.findIndex(page => page.$component === $vm); |
| | | const prevPage = currentPages[pageIndex - 1]; |
| | | if (prevPage) { |
| | | prevPage.$component?.$onMessage(action, nextData); |
| | | } |
| | | } else if (pageType === 'rootPage') { |
| | | const currentPages = getCurrentPages(); |
| | | const rootPage = currentPages[0]; |
| | | rootPage.$component?.$onMessage(action, nextData); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * 转换静态图片引用 |
| | | * @param assets |
| | | * @return {{}} |
| | | */ |
| | | static transAssets(assets = {}) { |
| | | const assets2 = {}; |
| | | Object.keys(assets).forEach(key => { |
| | | let asset = ''; |
| | | if (assets[key].indexOf('assets') >= 0) { |
| | | asset = assets[key].split('assets')[1]; |
| | | } else { |
| | | asset = assets[key].replace(/^[.\/\\]*/, '/'); |
| | | } |
| | | // 网页 |
| | | if (process.env.TARO_ENV === 'h5') { |
| | | assets2[key] = project.host.assetsPath + asset; |
| | | } |
| | | // 小程序 |
| | | else if (process.env.TARO_ENV === 'weapp') { |
| | | assets2[key] = $hostBoot.getHost() + project.host.assetsPath + asset; |
| | | } |
| | | }); |
| | | return assets2; |
| | | } |
| | | |
| | | } |