File was renamed from _cursor.ai/102-开发规范.md |
| | |
| | | --- |
| | | description: |
| | | globs: |
| | | alwaysApply: true |
| | | --- |
| | | |
| | | # 开发规范 |
| | | |
| | | - [开发规范](#开发规范) |
| | | - [规范宗旨](#规范宗旨) |
| | | - [命名问题](#命名问题) |
| | | - [命名需要具有实义](#命名需要具有实义) |
| | | - [文件命名](#文件命名) |
| | | - [界面层文件](#界面层文件) |
| | | - [数据控制层文件](#数据控制层文件) |
| | | - [组件文件](#组件文件) |
| | | - [请求文件](#请求文件) |
| | | - [样式命名](#样式命名) |
| | | - [界面样式](#界面样式) |
| | | - [组件样式](#组件样式) |
| | | - [JS 变量和属性的命名](#js-变量和属性的命名) |
| | | - [变量命名的特别约定](#变量命名的特别约定) |
| | | - [JS 方法的命名](#js-方法的命名) |
| | | - [在数据控制层](#在数据控制层) |
| | | - [在组件内](#在组件内) |
| | | - [书写问题](#书写问题) |
| | | - [JS 中的书写](#js-中的书写) |
| | | - [变量定义符](#变量定义符) |
| | | - [模版中的函数调用](#模版中的函数调用) |
| | | - [CSS 属性顺序](#css-属性顺序) |
| | | ## 开发规范宗旨 |
| | | |
| | | ## 规范宗旨 |
| | | |
| | | **代码首先是给人读的,其次才是给机器运行**,所以让代码容易阅读是应尽的责任 |
| | | |
| | | 除了尽可能不写难懂的代码外,我们还需要尽量遵守统一的规范,来帮助我们更高效率的相互阅读代码 |
| | | |
| | | ## 命名问题 |
| | | **代码首先是给人读的,其次才是给机器运行**,所以让代码容易阅读是你应尽的责任 |
| | | 包括但不限于以下内容: |
| | | - 给变量、函数命名时,需要具有实义 |
| | | - 避免使用难懂的语法或设计,用最简单的方式解决问题 |
| | | - 避免单块代码过长,拆分为多个更简短的函数或方法 |
| | | - 避免代码重复,通过封装函数、类或模块进行复用,封装遵守单一职责原则 |
| | | - 写注释应解释 "为什么" 而不仅仅是 "做什么" |
| | | |
| | | ### 命名需要具有实义 |
| | | |
| | | 命名的核心原则是名称含有具体的实体含义 |
| | | 命名的原则是名称中有具体实体含义的词汇 |
| | | |
| | | 比如没有实义的 |
| | | |
| | |
| | | |
| | | 改进后,从函数名一看便知,这是商品被选中了以后的需要进行的操作,又因为具备了在同一个页面的唯一性,能帮我们快速获取信息,知道这是哪个业务的哪个环节,大幅提高阅读效率,这就是实义 |
| | | |
| | | ### 文件命名 |
| | | |
| | | 常用文件命名约定 |
| | | |
| | | #### 界面层文件 |
| | | |
| | | 界面层文件(.vue、.scss),采用小驼峰命名 |
| | | |
| | | ``` |
| | | index.vue |
| | | index.scss |
| | | ``` |
| | | |
| | | #### 数据控制层文件 |
| | | |
| | | 数据控制层文件(.js),以固定前缀 P 开头,再接大驼峰 |
| | | |
| | | ``` |
| | | PIndex.js |
| | | ``` |
| | | |
| | | 数据层代码定义的名称,需要和文件名一致 |
| | | |
| | | ```js |
| | | export class PIndex extends Pilot {} |
| | | ``` |
| | | |
| | | #### 组件文件 |
| | | |
| | | 不论是公共组件还是页面子组件(.vue、.scss),都以固定前缀 C 开头,再接大驼峰 |
| | | |
| | | ``` |
| | | CMenu.vue |
| | | CMenu.scss |
| | | ``` |
| | | |
| | | 组件代码定义的名称,需要和文件名一致 |
| | | |
| | | ```js |
| | | // CMenu.vue 的组件名,必须是 CMenu |
| | | export default { |
| | | name: 'CMenu', |
| | | } |
| | | ``` |
| | | |
| | | #### 请求文件 |
| | | |
| | | 请求层文件(.js),以固定前缀 F 开头,再接大驼峰 |
| | | |
| | | ``` |
| | | FCommon.js |
| | | ``` |
| | | |
| | | 请求集合的代码定义名称,需要和文件名一致 |
| | | |
| | | ```js |
| | | // FCommon.js 的类名称,必须是 FCommon |
| | | class FCommon extends Fetcher {} |
| | | |
| | | // FCommon.js 代表的类的实例名称,则是 $fetchCommon |
| | | export const $fetchCommon = new FCommon(); |
| | | ``` |
| | | |
| | | ### 样式命名 |
| | | |
| | | 样式名的命名,采用横杠连接 |
| | | |
| | | ```css |
| | | .page-name {} |
| | | ``` |
| | | |
| | | #### 界面样式 |
| | | |
| | | 任何一个界面必定包含众多样式,所以: |
| | | |
| | | * 最父级样式名固定,与界面名称一直 |
| | | * 中间层,需要以父级为前缀,接板块说明 |
| | | * 末端则可单名,且尽量不含实义 |
| | | |
| | | ```css |
| | | /** 在界面 userList.vue 中,最父级样式名名称固定 **/ |
| | | .user-list { |
| | | |
| | | /** 中间多层,以父级为前缀 **/ |
| | | .user-list-title { |
| | | |
| | | /** 末端可单名,尽量非实义 **/ |
| | | .left, |
| | | .text, |
| | | .icon, |
| | | .sub, |
| | | .close {} |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | #### 组件样式 |
| | | |
| | | 组件样式名必须已 `c-` 开头,最父级样式名必须与组件名挂钩 |
| | | |
| | | 例如,组件 CMenu.vue 中,最父级样式名必须是: |
| | | |
| | | ```css |
| | | .c-menu {} |
| | | ``` |
| | | ## 常见命名要求 |
| | | |
| | | ### JS 变量和属性的命名 |
| | | |
| | |
| | | ```js |
| | | // 允许 is 开头的变量名 |
| | | let isOpened = false; |
| | | // 更好的命名 |
| | | let selectorOpened = false; |
| | | ``` |
| | | |
| | | **事件变量用 evt** |
| | |
| | | } |
| | | ``` |
| | | |
| | | ## 书写问题 |
| | | ### 样式命名 |
| | | |
| | | 书写规则都由编辑器自动格式化即可,这里主要说明非格式化的几点约定 |
| | | 样式名的命名,采用横杠连接 |
| | | |
| | | ```css |
| | | .page-name {} |
| | | ``` |
| | | |
| | | #### 界面样式 |
| | | |
| | | 任何一个界面必定包含众多样式,所以: |
| | | |
| | | * 最父级样式名固定,与界面名称一直 |
| | | * 中间层,需要以父级为前缀,接板块说明 |
| | | * 末端则可单名,且尽量不含实义 |
| | | |
| | | ```css |
| | | /** 在界面 userList.vue 中,最父级样式名名称固定 **/ |
| | | .user-list { |
| | | |
| | | /** 中间多层,以父级为前缀 **/ |
| | | .user-list-title { |
| | | |
| | | /** 末端可单名,尽量非实义 **/ |
| | | .left, |
| | | .text, |
| | | .icon, |
| | | .sub, |
| | | .close {} |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | #### 组件样式 |
| | | |
| | | 组件样式名必须已 `c-` 开头,最父级样式名必须与组件名挂钩 |
| | | |
| | | 例如,组件 CMenu.vue 中,最父级样式名必须是: |
| | | |
| | | ```css |
| | | .c-menu {} |
| | | ``` |
| | | |
| | | |
| | | ### 文件命名 |
| | | |
| | | 常用文件命名约定 |
| | | |
| | | #### 界面层文件 |
| | | |
| | | 界面层文件(.vue、.scss),采用小驼峰命名 |
| | | |
| | | ``` |
| | | index.vue |
| | | index.scss |
| | | ``` |
| | | |
| | | #### 数据控制层文件 |
| | | |
| | | 数据控制器文件(.js),以固定前缀 P 开头,再接大驼峰 |
| | | |
| | | ``` |
| | | PIndex.js |
| | | ``` |
| | | |
| | | 数据层代码定义的名称,需要和文件名一致 |
| | | |
| | | ```js |
| | | export class PIndex extends Pilot {} |
| | | ``` |
| | | |
| | | #### 组件文件 |
| | | |
| | | 不论是公共组件还是页面子组件(.vue、.scss),都以固定前缀 C 开头,再接大驼峰 |
| | | |
| | | ``` |
| | | CMenu.vue |
| | | CMenu.scss |
| | | ``` |
| | | |
| | | 组件代码定义的名称,需要和文件名一致 |
| | | |
| | | ```js |
| | | // CMenu.vue 的组件名,必须是 CMenu |
| | | export default { |
| | | name: 'CMenu', |
| | | } |
| | | ``` |
| | | |
| | | #### 请求文件 |
| | | |
| | | 请求层文件(.js),以固定前缀 F 开头,再接大驼峰 |
| | | |
| | | ``` |
| | | FCommon.js |
| | | ``` |
| | | |
| | | 请求集合的代码定义名称,需要和文件名一致 |
| | | |
| | | ```js |
| | | // FCommon.js 的类名称,必须是 FCommon |
| | | class FCommon extends Fetcher {} |
| | | |
| | | // FCommon.js 代表的类的实例名称,则是 $fetchCommon |
| | | export const $fetchCommon = new FCommon(); |
| | | ``` |
| | | |
| | | ## 常见书写要求 |
| | | |
| | | ### 基础书写要求 |
| | | |
| | | 例如: |
| | | - 使用四个空格代替 tab 进行缩进(包括代码和文档) |
| | | - 单行代码宽度最多100个字符 |
| | | - js 代码使用单引号 |
| | | |
| | | 更多规则请参考根目录 `.prettierrc` 文件 |
| | | |
| | | ### JS 中的书写 |
| | | |
| | |
| | | * 对于普通数据,如果明确要变更变量值,才使用 `let` |
| | | * 对于引用数据,如果明确需要重新赋值一个引用对象,才使用 `let` |
| | | |
| | | #### 变量判断 |
| | | |
| | | 为了避免弱类型带来的bug追踪困难,变量判断需要使用恒等号,必须判断类型一致 |
| | | |
| | | ```js |
| | | // 需要同时判断值和类型 |
| | | if (order.state === 1) {} |
| | | ``` |
| | | |
| | | #### 模版中的函数调用 |
| | | |
| | | 模版中调用函数,必须显式的书写 evt 变量和箭头函数,即: `evt => fncName()` |
| | | 我们把 Taro 自身组件视为普通元素,元素绑定事件使用 `@tap` 的方式,非元素皆是组件,组件使用 `:onClick` 的方式绑定 |
| | | - 模版中调用函数,为了便于阅读,必须显式的书写 evt 变量和箭头函数,即: `evt => fncName()`,**这是规范要求,不是代码冗余** |
| | | - 把 Taro 自身组件视为普通元素,元素绑定事件使用 `@tap` 的方式 |
| | | - 非元素皆是组件,组件使用 `:onClick` 的方式绑定 |
| | | |
| | | 例如: |
| | | ```html |
| | | <!-- 元素绑定事件使用 --> |
| | | <view @tap="() => onOpenOrderDetail()"></view> |
| | | <!-- 组件绑定事件使用 --> |
| | | <CMenu :onItemClick="evt => onMenuItemClick(evt)" /> |
| | | ``` |
| | | |
| | | #### 以 JSDoc 格式写方法注释 |
| | | |
| | | 公共代码中的方法都需要以 JSDoc 的格式写注释 |
| | | |
| | | ```js |
| | | export class Tools { |
| | | /** |
| | | * 显示消息提示框 |
| | | * @param {string} msg - 提示的消息内容 |
| | | * @param {number} [duration=2000] - 提示框显示时长(毫秒) |
| | | * @param {boolean} [mask=false] - 是否显示透明蒙层,防止触摸穿透 |
| | | */ |
| | | static toast(msg, duration = 2000, mask = false) { |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ### CSS 属性顺序 |
| | | |
| | | 为了避免 css 属性写重复,请按如下顺序书写: |