WebApp【公共组件库】@前端(For Git Submodule)
Tevin
2025-03-24 433cf5bfd7d0bd602c3147c15720a654ea47b028
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
---
description: 数据控制器基类,所有数据控制器都需要继承此类
globs: 
alwaysApply: false
---
 
# 数据控制层基类 Pilot.js
 
## 功能说明
 
Pilot 是数据控制层的基类
- 将 Vue 对象的数据绑定、方法绑定、生命周期等功能拆分出来,进行独立申明(拆分后界面层管显示,数据控制层管数据流转) 
- 增加跨页通讯、键名转换等相关的能力
- 每个数据控制器都需要继承此类
- 子类实例化后,再将申明的内容合并回去
 
## 引用方法
 
```js
import { Pilot } from '@components/bases/Pilot';
```
 
## 主要方法
 
 
### `createOptions(dataAdd)`
**功能**  
创建页面合并对象,将实例的属性和方法映射到页面合并对象中
 
**参数**  
- `dataAdd` (Object):需要添加到页面中的额外数据  
 
**返回值**  
- (Object):页面合并对象
 
 
**注意事项**  
- 如果 `dataAdd` 中包含 `assets` 属性,会自动调用 transAssets 转换其中的图片地址值
- `$` 开头的属性会被直接映射到合并对象中,同时去掉 `$` 前缀
- 非 `$` 开头的属性会被映射到合并对象的 `methods` 属性中
 
---
 
### `transAssets(assets)`
**功能**  
转换静态图片引用的路径,根据运行环境(H5 或小程序)生成图片实际发布的路径
 
**参数**  
- `assets` (Object):包含图片路径的对象  
 
**返回值**  
- (Object):转换后的图片路径对象
 
#### 静态图片地址转换说明
 
在目前项目体系设计下,由于不同项目(公众号、小程序、混合app)图片加载机制的不同,设置了一个统一的图片地址转换入口  
经过静态方法 transAssets 转换,可以获得图片实际发布的地址
 
**示例1**  
 
```javascript
const assets = { logo: 'assets/images/logo.png' };
const result = Pilot.transAssets(assets); // 输出转换后的图片实际发布地址
```
 
**示例2**  
 
```HTML
<template>
    <image :src="assets.homeNav1" mode="aspectFit" />
</template>
```
 
```js
export default {
    name: 'index',
    ...new PIndex().createOptions({
        // 首页菜单图片,会全部经过 transAssets 进行路径转换,转换为图片实际发布的地址
        assets: {
            homeNav1: 'assets/img/home-nav-01.png',
            homeNav2: 'assets/img/home-nav-02.png',
            homeNav3: 'assets/img/home-nav-03.png',
        },
    }),
};
```
 
**注意事项**  
移动端的图片不要使用 css 背景,而是使用 image 图片元素,再填充由 transAssets 生成的实际发布地址
 
## 页面合并流程
 
`createOptions` 是类 Pilot 的核心方法,此方法将独立申明的信息转换为合并对象,以方便原 Vue 对象进行合并
 
### 第一步:生成合并对象
 
* 扫描当前类,以 `$` 开头的属性或方法,去掉 `$` 符后,直接作为 Vue 的属性或方法准备合并
* 扫描当前类,非以 `$` 开头的方法,作为 Vue 对象申明中 methods 的子级方法准备合并
* 生成合并对象,用以进行合并
 
```js
// 数据控制器中,用 $ 开头的视为 Vue 属性或方法
export class PIndex extends Pilot {
    $data() {
        return {
            a: 1,
        };
    }
    $computed = {
        a2() {},
    };
    $mounted() {}
}
 
// 合并后的实际效果
const Component = Vue.extend({
    data() {
        return {
            a: 1,
        };
    },
    computed: {
        a2() {},
    },
    mounted() {},
});
```
 
```js
// 数据控制器中,非 $ 开头的,转到 methods 中
export class PIndex extends Pilot {
    onOpenSelector() {}
}
 
// 合并后的实际效果
const Component = Vue.extend({
    methods: {
        onOpenSelector() {},
    },
});
```
 
注意:不能在数据控制器中定义 $name、$components、$methods 这三项,因为实际合并时会覆盖
 
### 第二步:实际合并
 
数据控制层和界面层实际的合并,其实是写在界面层上  
由界面层实例化数据控制层,并使用其基类的 createOptions 方法生成选项,再合并进原 Vue 对象
 
```js
// 引入界面层对应数据控制器
import { PPageName } from '@pilots/pilotGroup/PPageName';
 
export default {
    name: 'PageName',
    components: {},
    // 示例化数据控制器,由实例生成 Vue 选项,再展开合并到界面 Vue 对象上
    ...new PPageName().createOptions(),
};
```
## 页面能力扩展
 
### 跨页面通讯
 
Taro 的跨页面通讯能力,仅小程序可用,非小城不能跨页通讯非常不方便  
因此,使用 createOptions 创建合并对象时,给页面的 Vue 实例,增加了跨页面通讯的方法,兼容所有平台
 
**跨页发送:$poster**
 
此方法挂载到 vue 实例的 this 上
 
```js
this.$poster(direction, action, data);
```
 
参数:  
- `direction` (String,必填):发送去向,有两值:
  - `'nextPage'`:发生给下一页(如果正在创建,会等待创建成功后再传递)
  - `'prevPage'`:发送给上一页
- `action` (String,必填):动作名称  
- `data` (any,可选):携带数据
 
例如:
 
```js
export class PList extends Pilot {
    onSaveSetting() {
        // 设置保存后,通知上页
        this.$poster('prevPage', 'settingChanged');
    }
}
```
 
**跨页接收:$onMessage**
 
此方法的用法,类似生命周期的钩子
 
```js
$onMessage(action, data) {}
```
 
例如:
 
```js
export class PIndex extends Pilot {
 
    $onMessage(action, data) {
        // 接收消息,设置已变更
        if (action === 'settingChanged') {
            // do something
        }
    }
}
```
 
### 跨端通讯
 
当我们进混合 APP 开发时,我们需要与 java 层进行通讯,使用 createOptions 创建合并对象时,增加了跨通讯的能力
 
(TODO:更多跨端通讯明细待续)