From 89d0aaed29f344ff46c6fbc9b6e6e92b2922a0d7 Mon Sep 17 00:00:00 2001 From: Tevin <tingquanren@163.com> Date: Thu, 27 Feb 2025 11:59:58 +0800 Subject: [PATCH] 知识库文档,新增项目规范 --- _knowledges/02-项目规范.md | 343 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 343 insertions(+), 0 deletions(-) diff --git "a/_knowledges/02-\351\241\271\347\233\256\350\247\204\350\214\203.md" "b/_knowledges/02-\351\241\271\347\233\256\350\247\204\350\214\203.md" new file mode 100644 index 0000000..161c067 --- /dev/null +++ "b/_knowledges/02-\351\241\271\347\233\256\350\247\204\350\214\203.md" @@ -0,0 +1,343 @@ +# 项目规范 + +**代码首先是给人读的,其次才是给机器运行**,所以让代码容易阅读是应尽的责任 + +除了尽可能不写难懂的代码外,我们还需要尽量遵守统一的规范,来帮助我们更高效率的相互阅读代码 + +## 命名 + +### 命名需要具有实义 + +命名的核心原则是名称含有具体的实体含义 + +比如没有实义的 + +```js +const onClick = () => null; // 不好的命名 +``` + +因为 `click` 可以发生在任何元素上,从这个名称上无法分辨业务种类,所以我们认为这个函数名没有实义,需要改进一下: + +```js +const onProductSelected = () => null; // 良好的命名 +``` + +改进后,从函数名一看便知,这是商品被选中了以后的需要进行的操作,又因为具备了在同一个页面的唯一性,能帮我们快速获取信息,知道这是哪个业务的哪个环节,大幅提高阅读效率,这就是实义 + +### 文件命名 + +常用文件命名约定 + +#### 界面层文件 + +界面层文件(.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 +// 变量 +const name = ''; +const orderList = ''; +// 属性 +const user = { + name: '', + lastOrder: '', +}; +``` + +#### 变量命名的特别约定 + +**变量名允许 is 开头** +变量名不能用动词开头,但是允许 is 作为特例 + +```js +// 允许 is 开头的变量名 +let isOpened = false; +``` + +**事件变量用 evt** +事件 event 的简写,必须是 evt(不能用单字面 e ) + +```html +<view @tap="evt => onOrderClick(evt)"></view> +<CMenu :onClick="evt => onMenuItemClick(evt)" /> +``` + +**报错信息用 err** +报错 error 的简写,必须是 err(不能用单字面 e ) + +```js +Taro.request({ + fail: err => {}, +}); +``` + +**后端数据 res** +后端返回数据,优先采用 resource 的简写 res + +```js +$fetch.getEquipments().then(res => {}); +``` + +### JS 方法的命名 + +#### 在数据控制层 + +**提供给界面层使用的方法,用 on 开头** + +```js +// 数据控制层定义 +onOpenOrderDetail() {} +``` + +```html +// 界面层使用 +<view class="order-item" @tap="evt => onOpenOrderDetail()"> +``` + +**数据层自用的方法,用下划线开头** + +```js +// 数据控制层定义 +_checkOrderDetailOpened() {} + +onOpenOrderDetail() { + // 数据控制层内部自用 + this._checkOrderDetailOpened(); +} +``` + +#### 在组件内 + +**接收父级方法的时候,用 on 开头** + +```js +export default { + props: { + // 选择会员后的回调 + onUserSelected: Function, + }, +} +``` + +**组件自身模版绑定的时候,用 handle 开头** + +```js +export default { + methods: { + // 组件层定义 + handleUserSelected() {} + } +} +``` + +```html +// 组件层自身模板绑定 +<view class="user-item" @tap="evt => handleUserSelected()"> +``` + +**函数相互调用的时候,用下划线开头** + +```js +export default { + methods: { + // 组件层定义 + _checkUser() {}, + handleUserSelected() { + // 组件层内部自用 + this._checkUser() + } + } +} +``` + +**给父级ref的引用进行调用的方法,使用 $ 开头** + +```js +export default { + methods: { + // 组件层定义 + $close() {} + } +} +``` + +父级 + +```html +<CUserDetail ref="userDetail"> +``` + +```js +onCloseAll() { + // 父级 ref 调用 + this.$refs.userDetail.$close() +} +``` + +## 书写 + +书写规则都由编辑器自动格式化即可,这里主要说明非格式化的几点约定 + +### JS 中的书写 + +#### 变量定义符 + +弃用 `var` ,改用 `const` 与 `let` ,且优先使用 `const` ,除非要改值 + +```js +const name = 'Tevin'; +``` + +```js +let count = 0; +count++; +``` + +注意,const 定义的对象,其属性是可以改值的 + +```js +const search = { + count: 1 +}; +search.count++; // 允许运行 +search = {}; // 报错 +``` + +所以: +* 对于普通数据,如果明确要变更变量值,才使用 `let` +* 对于引用数据,如果明确需要重新赋值一个引用对象,才使用 `let` + +#### 模版中的函数调用 + +模版中调用函数,必须显式的书写 evt 变量和箭头函数,即: `evt => null` + +```html +<view @tap="() => onOpenOrderDetail()"></view> +<CMenu :onItemClick="evt => onMenuItemClick(evt)" /> +``` + +### CSS 属性顺序 + +按顺序如下: + +* **文档流属性** + display, position, float, clear, visibility, table-layout 等 + +* **大小属性** + width, height, margin, padding 等 + +* **文字排版属性** + font, line-height, text-align, text-indent, vertical-align 等 + +* **装饰性属性** + color, background, border, opacity, shadow, cursor 等 + +* **生成内容属性** + content, list-style, quotes 等 + +* **二次渲染属性** + zoom, transform 等 + +* **动画属性** + transition, animation 等 -- Gitblit v1.9.1