/**
|
* Pilot
|
* @author Tevin
|
*/
|
|
import Taro, { getCurrentInstance, getCurrentPages } from '@tarojs/taro';
|
import { $hostBoot } from '@components/bases/HostBoot';
|
import project from '@project';
|
|
export class Pilot {
|
constructor() {}
|
|
$data() {
|
return {};
|
}
|
|
createOptions(dataAdd) {
|
const options = {
|
methods: {},
|
};
|
const names = [];
|
let parent = null;
|
// 实例本身的字段
|
Object.getOwnPropertyNames(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 (name === 'constructor' || name === '$methods') {
|
return;
|
}
|
if (/^\$/.test(name)) {
|
if (name === '$data' && typeof dataAdd !== 'undefined') {
|
// 转换 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];
|
}
|
} else {
|
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 秒,检测下一页是否存在,如果 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);
|
setTimeout(() => {
|
nextPage.$component?.$onMessage(action, nextData);
|
}, 0);
|
}
|
}, 50);
|
}
|
// 传递消息到上一页,上一页的上一页,依次直到首页
|
else if (pageType === 'prevPage') {
|
const currentPages = getCurrentPages();
|
let pageIndex = currentPages.findIndex(page => page.$component === $vm);
|
while (pageIndex - 1 >= 0) {
|
const prevPage = currentPages[pageIndex - 1];
|
if (prevPage) {
|
prevPage.$component?.$onMessage(action, nextData);
|
}
|
pageIndex--;
|
}
|
}
|
// 传递消息到原地新页(redirectTo原地新开页面)
|
else if (pageType === 'sitePage') {
|
const currentPages = getCurrentPages();
|
const pageIndex = currentPages.findIndex(page => page.$component === $vm);
|
const pagePath = currentPages[pageIndex].$taroPath
|
// 持续 3 秒,检查当前页是否新开,如果 3 秒内没有新开,忽略
|
let count = 0;
|
const timer = setInterval(() => {
|
if (++count > 60) {
|
clearInterval(timer);
|
}
|
const currentPages = getCurrentPages();
|
const sitePage = currentPages[pageIndex];
|
if (sitePage.$component !== $vm || sitePage.$taroPath !== pagePath) {
|
clearInterval(timer);
|
setTimeout(() => {
|
sitePage.$component?.$onMessage(action, nextData);
|
}, 0);
|
}
|
}, 50);
|
}
|
};
|
}
|
|
/**
|
* 转换静态图片引用
|
* @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;
|
}
|
}
|