WebApp【公共组件库】@前端(For Git Submodule)
Tevin
2025-03-24 16392b305809f9f2f6f66335c4934050411a6041
bases/Pilot.js
@@ -3,6 +3,10 @@
 * @author Tevin
 */
import Taro, { getCurrentInstance, getCurrentPages } from '@tarojs/taro';
import { $hostBoot } from '@components/bases/HostBoot';
import project from '@project';
export class Pilot {
    constructor() {
@@ -16,20 +20,36 @@
        const options = {
            methods: {},
        };
        Object.getOwnPropertyNames(Object.getPrototypeOf(this)).forEach(name => {
        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') {
                    // 当有传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];
                }
@@ -37,7 +57,102 @@
                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;
    }
}