# 项目介绍 这是一个编程项目,用于移动端网页开发 ## 技术栈 * 语法框架: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 这三项,因为实际合并时会覆盖 ## 新页面模板 新建页面时,可使用如下空白页面模板 ### 页面层 #### 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(); ```