WebApp【公共组件库】@前端(For Git Submodule)
Tevin
2022-11-16 f697aa22096d5629c77328ea876dc07949d116c9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/**
 * 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 = [];
        // 实例本身的字段
        Object.getOwnPropertyNames(this).forEach(name => names.push(name));
        // 类的字段
        Object.getOwnPropertyNames(Object.getPrototypeOf(this)).forEach(name => names.push(name));
        // 传递
        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 秒,检测下一页是否存在
                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;
    }
 
}