JAVASCRIPT 开发规范
1. 对象
-
使用直接量创建对象
// bad const item = new Object() // good const item = {} -
不要使用保留字作为键名
// bad const userInfo = { class: '1', privated: true } // good const userInfo = { type: '1' }
2. 数组
-
使用直接量创建数组
// bad const item = new Array() // good const item = [] -
向数组增加元素时使用
push// bad const item = [] item[item.length] = 'Explosion' // good item.push('Explosion') -
需要拷贝浅数组的时候使用slice
const len = items.length; const itemsCopy = []; const i; // bad for (i = 0; i < len; i++) { itemsCopy[i] = items[i]; } // good itemsCopy = items.slice();
3. 字符串
-
使用单引号
''包裹字符串// bad let name = "yueyun" // good let name = 'yueyun' -
超过 100 个字符的字符串应该使用连接符写成多行
// bad const errorMessage = 'This is a super long error that was thrown because \ of Batman. When you stop to think about how Batman had anything to do \ with this, you would get nowhere \ fast.'; // good const errorMessage = 'This is a super long error that was thrown because ' + 'of Batman. When you stop to think about how Batman had anything to do ' + 'with this, you would get nowhere fast.';
4. 函数
-
函数表达式
// 匿名函数表达式 var anonymous = function() { return true; }; // const test = () => { return true } // 命名函数表达式 var named = function named() { return true; }; // 立即调用的函数表达式(IIFE) (function () { console.log('Welcome to the Internet. Please follow me.'); }()); -
不要再一个代码块中(if while 等)中去声明函数
// bad if (currentUser) { function test() { console.log('Nope.'); } } // good var test; if (currentUser) { test = function test() { console.log('Yup.'); }; } -
不要将参数命令为
arguments因为这个函数内置的关键字对象// bad function nope(name, options, arguments) { // ...stuff... } // good function yup(name, options, args) { // ...stuff... }
5. 属性
-
使用
.来访问对象的属性const luke = { jedi: true, age: 28 }; // bad const isJedi = luke['jedi']; // good const isJedi = luke.jedi; -
当通过变量访问属性时使用中括号
[]。var luke = { jedi: true, age: 28 }; function getProp(prop) { return luke[prop]; } var isJedi = getProp('jedi');
6. 变量
-
优先使用
const和let去声明// bad var name = 'yueyun' // good let name = 'yueyun' -
在作用域顶部声明变量。这将帮你避免变量声明提升相关的问题。
// bad function () { test(); console.log('doing stuff..'); //..other stuff.. const name = getName(); if (name === 'test') { return false; } return name; } // good function () { const name = getName(); test(); console.log('doing stuff..'); //..other stuff.. if (name === 'test') { return false; } return name; } // bad - 不必要的函数调用 function () { const name = getName(); if (!arguments.length) { return false; } this.setFirstName(name); return true; } // good function () { const name; if (!arguments.length) { return false; } name = getName(); this.setFirstName(name); return true; }
React开发规范
1. 基本规则
- 一个文件声明一个组件:尽管可以在一个文件中声明多个 React 组件,但是最好不要这样做;推荐一个文件声明一个 React 组件,并只导出一个组件;
- 使用
JSX表达式:不要使用React.createElement的写法 React 18尽量使用函数组件
2.命名规范
-
扩展名:用
.jsx || .tsx作为组件的扩展名 -
文件名:用大驼峰作为文件名,如:
ReservationCard.tsx -
命名参数:React组件用大驼峰,组件实例用小驼峰
// bad import reservationCard from './ReservationCard'; // good import ReservationCard from './ReservationCard'; // bad const ReservationItem = <ReservationCard />; // good const reservationItem = <ReservationCard />; -
组件命名:文件名作为组件名。例如:
ReservationCard.jsx应该用ReservationCard作为参数名。然而,对于一个文件夹里的跟组件,应该用index.jsx作为文件名,同时用文件夹作为组件名// bad import Footer from './Footer/Footer' // bad import Footer from './Footer/index' // good import Footer from './Footer' -
Props命名:避免用 DOM 组件的属性名表达不同的意义
// bad <MyComponent style="fancy" /> // bad <MyComponent className="fancy" /> // good <MyComponent variant="fancy" />
3.对齐
对 JSX 语法使用这些对齐风格。
// Foo 里面的标签正常缩进
<Foo
superLongParam="bar"
anotherSuperLongParam="baz"
>
<Quux />
</Foo>
// bad
{showButton &&
<Button />
}
// bad
{
showButton &&
<Button />
}
// good
{showButton && (
<Button />
)}
// good
{showButton && <Button />}
4.引用
在 JSX 属性中用双引号("),但是在js里用单引号(')
Why? 正常的 HTML 属性也通常使用双引号而不是单引号,所以 JSX 属性也使用这个约定。
// bad
<Foo bar='bar' />
// good
<Foo bar="bar" />
// bad
<Foo style={{ left: "20px" }} />
// good
<Foo style={{ left: '20px' }} />
5.属性
props 用小驼峰
// bad
<Foo
UserName="hello"
phone_number={12345678}
/>
// good
<Foo
userName="hello"
phoneNumber={12345678}
/>
如果 prop 的值是 true 可以忽略这个值,直接写 prop 名就可以。
// bad
<Foo
hidden={true}
/>
// good
<Foo
hidden
/>
// good
<Foo hidden />
避免用数组下标作为 key 属性,推荐用稳定的 ID Why? 不使用稳定杆的 ID is an anti-pattern 会对组件性能产生消极影响,并且组件状态容易出现问题。 如果数组元素可能会发生变化,我们不推荐使用下标作为key。
// bad
{todos.map((todo, index) =>
<Todo
{...todo}
key={index}
/>
)}
// good
{todos.map(todo => (
<Todo
{...todo}
key={todo.id}
/>
))}
6. 关于Refs请勿过度使用
7. Hook规则
只在最顶层使用 Hook
不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层调用他们。遵守这条规则,你就能确保 Hook 在每一次渲染中都按照同样的顺序被调用。这让 React 能够在多次的 useState 和 useEffect 调用之间保持 hook 状态的正确。(如果你对此感到好奇,我们在下面会有更深入的解释。)
只在 React 函数中调用 Hook
不要在普通的 JavaScript 函数中调用 Hook。你可以:
✅ 在 React 的函数组件中调用 Hook
✅ 在自定义 Hook 中调用其他 Hook
遵循此规则,确保组件的状态逻辑在代码中清晰可见。
8.状态管理规范
约定:
- 当我们项目中复杂程度较低时,建议只用state就可以了
- 如果仅仅因为存在多层传递数据的场景,不建议使用mobx或redux,可使用context解决
- 如果仅仅因为夸路由数据共享,不建议使用mobx或redux,可使用context或者路由传参解决
- 如果业务复杂,需要使用第三方状态管理解决复杂度,看下一条
- 当项目复杂度一般,小规模团队或开发周期较短、要求快速上线时,推荐使用mobx
- 当项目复杂度较高,团队规模较大或要求对事件分发处理可监控可回溯时,推荐使用redux,可尝试使用 rematch或@reduxjs/toolkit,减少模板代码
- 如果后端数据符合REST风格且数据格式统一且重复数据较多,推荐使用扁平化处理数据。
9.目录结构
├─package-lock.json
├─package.json ------------ // 项目配置
├─postcss.config.js ------- // postcss 配置
├─public ------------------ // 公开目录
│ ├─favicon.ico
│ └─index.html
├─README.md ---------- // 项目说明
└─src --------------------- // 源码目录
├─App.tsx --------------- // 根组件
├─assets ---------------- // 静态资源目录
│ └─images -------------- // 图片目录
│ └─logo.png ------ // logo 图片
│ └─svg -------------- // 图标目录
│ └─logo.svg ------ // logo 图片
├─components ------------ // 公共组件目录
│ └─Menu ---------------- // 公共组件
│ ├─index.tsx ---------- // 组件文件
│ └─index.scss ------ // 组件样式
├─constants ---------------- // 项目常量
│ └─index.ts
├─libs ------------------ // 第三方库目录
├─index.tsx --------------- // 主入口
├─router ---------------- // 路由配置
│ └─index.tsx
├─store ----------------- // 状态管理
│ ├─module.ts // 模块
│ └─index.ts // 入口
├─tests ----------------- // 测试目录
├─utils ----------------- // 工具目录
│ ├─a.ts
│ └─index.ts
└─pages ----------------- // 视图目录
└─Home ---------------- // 页面组件
├─components -------- // 子组件目录
│ └─Header
│ ├─index.tsx
│ └─index.scss
└─index.tsx ---------- // 组件主体