# 数据控制层基类 Pilot.js - [数据控制层基类 Pilot.js](#数据控制层基类-pilotjs) - [功能说明](#功能说明) - [引用方法](#引用方法) - [主要方法](#主要方法) - [`createOptions(dataAdd)`](#createoptionsdataadd) - [`transAssets(assets)`](#transassetsassets) - [静态图片地址转换说明](#静态图片地址转换说明) - [页面合并流程](#页面合并流程) - [第一步:生成合并对象](#第一步生成合并对象) - [第二步:实际合并](#第二步实际合并) - [页面能力扩展](#页面能力扩展) - [跨页面通讯](#跨页面通讯) - [跨端通讯](#跨端通讯) ## 功能说明 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 ``` ```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:更多跨端通讯明细待续)