# 工程介绍 - [工程介绍](#工程介绍) - [工程介绍](#工程介绍-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(); ```