# 工程介绍
- [工程介绍](#工程介绍)
- [工程介绍](#工程介绍-1)
- [技术栈](#技术栈)
- [工程目录结构](#工程目录结构)
- [短路径映射](#短路径映射)
- [页面构成](#页面构成)
- [界面层和数据控制层的拆分](#界面层和数据控制层的拆分)
- [新页面模板](#新页面模板)
- [界面层空白模板](#界面层空白模板)
- [H5 空白界面模板](#h5-空白界面模板)
- [小程序空白界面模板](#小程序空白界面模板)
- [空白样式文件模板](#空白样式文件模板)
- [数据控制层空白模板](#数据控制层空白模板)
- [数据控制器空白模板](#数据控制器空白模板)
- [请求集空白模板](#请求集空白模板)
## 工程介绍
这是一套Web前端开发的工程文档,用于指导移动端(H5网页、混合App、小程序等)的开发
## 技术栈
- 语法框架:Vue(v2.5.0)
- 工程框架:Taro(v3.2.13)
- 显示框架:Taro-UI-Vue(v1.0.0-beta.10)
- 样式:Sass
说明:使用时,优先使用公共组件库的组件,其次是 Taro-UI-Vue 的组件,最后才是 Taro 本身的基础组件
## 工程目录结构
工程主要目录及其用途
- root/(根目录)
- public/(静态资源目录)
- src/(开发源码目录)
- components/(公共资源目录)
- bases/(公共基类目录)
- common/(公共工具目录)
- forms/(公共表单组件目录)
- layout/(公共排版组件目录)
- plugins/(公共复杂组件目录)
- fetchers/(请求层目录)
- FName.js(请求集)
- pages/(界面层目录)
- pageGroup/(界面层分组目录)
- pageName/(界面层单页目录)
- cmpt/(界面子组件目录)
- CName.vue(子组件)
- cName.scss(子组件样式)
- page.vue(界面)
- page.scss(界面样式)
- pilots/(数据控制层目录)
- _overall/(全局数据控制目录)
- pilotGroup/(数据控制层分组目录)
- mixin/(混合件目录)
- MName.js(混合件)
- PName.js(数据控制器)
### 短路径映射
工程资源引用时,通常使用更短的引用路径:
* `@components` 代表 `root/src/components`
* `@fetchers` 代表 `root/src/fetchers`
* `@pages` 代表 `root/src/pages`
* `@pilots` 代表 `root/src/pilots`
例如:'@components/layout/h5Page' 实际引用的是 'root/src/components/layout/h5Page'
## 页面构成
当我们说组件的时候,就是指普通 Vue 组件
当我们说业务页面的时候,则是由**界面层**和**数据控制层**两部分组成
同时页面层有子组件,数据层关联请求层,结构如下
- 业务页面:
- 界面层(root/src/pages/pageGroup/pageName/page.vue)
- 界面子组件(root/src/pages/pageGroup/pageName/cmpt/CName.vue)
- 数据控制层(root/src/pilots/pilotsGroup/PName.js)
- 请求层(root/src/fetchers/FName.js)
### 界面层和数据控制层的拆分
一个业务页面的界面层和数据控制层,实际上是对一个 Vue 组件的拆分,最终运行的时候,还是会合二为一,还原成原本的 Vue 实例
因此,数据控制层其实是对这个 Vue 实例部分功能的一种转写,类似于语法糖
**数据控制层写法**
例如:
```js
// 数据控制器
export class PIndex extends Pilot {
$data() {
return {
a: 1,
};
}
$computed = {
a2() {},
};
$mounted() {}
onOpenSelector() {}
}
```
会转换成
```js
// 标准 Vue
const Component = Vue.extend({
data() {
return {
a: 1,
};
},
computed: {
a2() {},
},
methods: {
onOpenSelector() {},
},
mounted() {},
});
```
更多细节,请参照《数据控制层基类Pilot》
## 新页面模板
新建页面时,页面初始内容,可参考如下空白模板
### 界面层空白模板
#### H5 空白界面模板
H5 界面需要 CPage、CContent、CNavBar 这三个基础页面组件
```html
/**
* pageName - 页面名称
* @author 作者
*/
```
#### 小程序空白界面模板
```html
/**
* pageName - 页面名称
* @author 作者
*/
```
#### 空白样式文件模板
```css
/**
* pageName - 页面名称
* @author 作者
*/
@import "../../../components/common/sassMixin";
.page-name {}
```
### 数据控制层空白模板
#### 数据控制器空白模板
```js
/**
* PPageName - 页面名称
* @author 作者
*/
import Taro from '@tarojs/taro';
import {
Pilot
} from '@components/bases/Pilot';
import {
$fetchCommon
} from '@fetchers/FCommon';
export class PPageName extends Pilot {
$data() {
return {};
}
$mounted() {
this.onLoadDataResource();
}
// 加载用户详情
onLoadDataResource() {
Taro.showLoading();
$fetchCommon.getPageDetail()
.then(res => {
Taro.hideLoading();
if (!res) {
return;
}
// do something
});
}
}
```
说明:请求异常由请求层的基类自动处理,数据控制层跳过错误的逻辑,只处理请求成功的后续业务
#### 请求集空白模板
```js
/**
* FCommon - 公用请求集
* @author 作者
*/
import {
Fetcher
} from '@components/bases/Fetcher';
class FCommon extends Fetcher {
constructor() {
super({
// url前缀(本地路径, 服务器路径)
urlPrefix: ['/api/common/', '/serverPath/'],
});
}
// 读取页面详情
getPageDetail() {
const url = this.spellURL('getPageDetail', 'page/Detail');
const send = {};
return this.post(url, send);
}
}
export const $fetchCommon = new FCommon();
```