---
|
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:更多跨端通讯明细待续)
|