# 项目介绍
这是一个编程项目,用于移动端网页开发
## 技术栈
* 语法框架:Vue(v2.5.0)
* 项目框架:Taro(v3.2.13)
* 显示框架:Taro-UI-Vue(v1.0.0-beta.10)
* 样式:Sass
* 相关插件
- 时间插件:moment(v2.29.1)
## 项目目录结构
项目主要目录及其用途
* 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() {},
});
```
##### 数据控制层的 Vue 属性
数据控制器中的 Vue 属性,需要使用 $ 开头
```js
// 数据控制器
export class PIndex extends Pilot {
$data() {
return {
a: 1,
};
}
$computed = {
a2() {},
};
}
```
会转换成
```js
// 标准 Vue
const Component = Vue.extend({
data() {
return {
a: 1,
};
},
computed: {
a2() {},
},
});
```
##### 数据控制层的 Vue 方法
数据控制器中的 Vue 方法,不用写 methods 中,直接写最外层
```js
// 数据控制器
export class PIndex extends Pilot {
onOpenSelector() {}
}
```
会转换成
```js
// 标准 Vue
const Component = Vue.extend({
methods: {
onOpenSelector() {},
},
});
```
注意:数据控制器中不能使用 $name、$components、$methods 这三项,因为实际合并时会覆盖
#### 实际合并
数据控制层和界面层实际的合并,写在界面层上
```js
// 引入界面层对应数据控制器
import {
PPageName
} from '@pilots/pilotGroup/PPageName';
export default {
name: 'PageName',
components: {},
// 示例化数据控制器,由实例生成 Vue 选项,再展开合并到界面 Vue 对象上
...new PPageName().createOptions(),
};
```
## 新页面示例
新建页面时,页面初始内容,可参考如下空白示例
### 界面层
#### 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();
```