# frontend-development-specifications **Repository Path**: xiangyongjun/frontend-development-specifications ## Basic Information - **Project Name**: frontend-development-specifications - **Description**: 前端开发规范 - **Primary Language**: TypeScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2023-09-04 - **Last Updated**: 2023-09-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 前端开发规范(2023-09-03) ### 作者:向永俊 ## 一、命名规范 ### 1. 项目、目录、文件命名、(vue 文件除外) ``` 采用全小写形式,每个单词以中线分割 例:mall-management-system、image-util.ts、home-background.png ``` ### 2. vue 文件命名 ```vue ``` ### 3. 路由命名 ```typescript { path: '/sys-manage', // 全小写,中线分割 name: 'SysManage', // 大驼峰 component: Layout, meta: { title: '系统设置', icon: 'home-2-line', breadcrumbHidden: true, }, }, ``` ### 4. css 命名 ```scss ``` ### 5. 变量、函数命名 ```typescript // 采用小驼峰形式 const userInfo: string = 'abc' const getUserInfo = () => { return userInfo } ``` ### 6. 类、方法、属性命名 ```typescript // 类名使用大驼峰 class Human { // 属性使用小驼峰(开头下划线是私有属性,ts 新特性) _realName: string // 方法使用小驼峰 setRealName(realName: string) { this._realName = _realName } } ``` ### 7. 目录结构 ```typescript 项目 |--node_modules |--public |--src |--api // 请求接口目录 |--assets // 静态资源目录 |--config // 配置目录 |--dictionary // 字典目录 |--hooks // 自定义钩子目录 |--directives // 自定义指令目录 |--components // 公共组件目录 |--utils // 工具目录 |--pages // 页面目录 |--home |--Home.vue |--components // 页面子组件目录 |--HomeTree.vue |--HomeTable.vue |--stores // 页面共享数据目录 |--index.ts |--router // 路由目录 |--stores // 仓库目录 |--models // 模型目录 |--styles //样式目录 ``` ## 二、JavaScript 规范 ### 1. 定义变量尽量使用 const,避免使用 var ```typescript // 当变量是个对象时,请使用 const const a: Object = {} // 当变量是个数组时,请使用 const const b: Array = [] // 当变量定义后不会再改变,请使用 const const projectName: string = '测试项目' ``` ### 2. 如需改变原数组数据结构,但长度不变,请使用 Array.map ```typescript interface Human { name: string age: number } // 人类集合 const humans: Array = [{ name: '测试1', age: 10 }, { name: '测试2', age: 55 }] // 姓名集合 const names: Array = a.map(item => (item.name)) // 输出结果:names: ['测试1', '测试2'] ``` ### 3. 如需对数组元素进行累加操作,请使用 Array.reduce ```typescript const apples = [ { id: 1, amount: 10 }, { id: 1, amount: 100 } ] const totalAmount = apples.reduce((pre, cur) => (pre + cur.amount), 0) // 输出结果:totalAmount: 110 ``` ### 3. 尽量使用 async、await 语法糖将代码扁平化增加代码阅读性 ```typescript import { userLogin, getUserInfo } from '../api/user' // 反面教材 const login = (username: string, password: string) => { userLogin({ username, password }).then(res => { if (res.code === 200) { getUserInfo({ token: res.data.token }).then(res => { if (res.code === 200) { console.log(res.data) } }) } }) } // 正确写法 const login = async (username: string, password: string) => { const { code, data: { token } } = await userLogin({ username, password }) if (code !== 200) return const { code: code2, data: data2 } = await getUserInfo({ token: res.data.token }) if (code !== 200) return console.log(data2) } ``` ### 4. loading 需要在 finally 中关闭 ```typescript import { userLogin, getUserInfo } from '../api/user' // 反面教材 const login = async (username: string, password: string) => { wx.showLoading({ title: '正在登录...', mask: true }) const { code, data: { token } } = await userLogin({ username, password }) wx.hideLoading() } // 正确写法 const login = async (username: string, password: string) => { wx.showLoading({ title: '正在登录...', mask: true }) const { code, data: { token } } = await userLogin({ username, password }).finally(() => uni.hideLoading()) } // 正确写法 const login = async (username: string, password: string) => { wx.showLoading({ title: '正在登录...', mask: true }) try { const { code, data: { token } } = await userLogin({ username, password }) if (code !== 200) return const { code: code2, data: data2 } = await getUserInfo({ token: res.data.token }) if (code !== 200) return } catch { } finally { wx.hideLoading() } console.log(data2) } ``` ### 5. 尽量使用 === 代替 == ```typescript console.log(10 == '10') // true console.log(10 === '10') // false ``` ### 6. && 运算符的妙用 ```typescript const isLogin = true const hasVIP = true const joinRoom = () => { console.log('成功加入房间') } isLogin && hasVIP && joinRoom() // 输出结果:成功加入房间 ``` ### 7. || 逻辑运算符的妙用 ```typescript const result1 = null const result2 = false const result3 = 'result3' console.log(result1 || result2 || result2) // 输出结果:'result3' ``` ### 8. ?? 空值合并操作符的妙用 ```typescript const result1 = null const result2 = false const result3 = 'result2' console.log(result1 ?? result2 ?? result2) // 输出结果:false ``` ### 9. 函数简写 ```typescript // 优化前 async function sleep(time: number) { return new Promise((resolve) => { setTimeout(function() { resolve() }, time) }) } // 优化后 const sleep = async (time: number) => new Promise(resolve => setTimeout(resolve, time)) ``` ### 10. 三元运算符 ```typescript // 优化前 const a = 1 if (a === 1) console.log('是1') else console.log('非1') // 优化后 console.log(a === 1 ? '是1' : '非1') ``` ### 11. 可选链操作符 ```typescript // 优化前 const a = { b: null } if (a && a.b && a.b.c) console.log('c节点存在') // 优化后 if (a?.b?.c) console.log('c节点存在') ``` ### 12. 优化 if、else if 、else 分支 ```typescript // 优化前 const light = 'green' if (light === 'red') console.log('红灯') else if (light === 'green') console.log('绿灯') else if (light === 'yellow') console.log('黄灯') else console.log('灯坏了') // 优化后 const lights = { 'red': '红灯', 'green': '绿灯', 'yellow': '黄灯' } console.log(lights[light] || '灯坏了') ``` ### 13. 多个请求同时发送时,请使用 Promise.all ```typescript import { getHeaderData, getFooterData } from '../api/home' const getData = async () => { wx.showLoading({ title: '加载中...', mask: true }) const res = await Promise.all(getHeaderData(), getFooterData()).finally(() => wx.hideLoading()) if (res.some(item => item.code !== 200)) return console.log('数据加载完毕', res[0].data, res[1].data) } ``` ### 14. 尽量使用高阶函数解决问题 ```typescript filter、map、find、forEach、findIndex、reduce、some、every、sort 等 ``` ## 三、Vue 组件通讯规范 ### 1. 父传子、子传父(仅一对一时使用) ```vue