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