参考:
vue 风格指南
javascript.info 代码风格
clean-code-typescript
组件
类型 | 建议 | 举例 |
---|---|---|
组件名 | 多个单词,因为现有的以及未来的 HTML 元素是单个 | ErrorTipModel |
data | 函数 | data() { return {} } |
props | 应该尽量详细,至少需要指定其类型 | 详见下方 |
props 大小写 | camelCase | studentMessage |
v-for | 指定key | 详见下方 |
避免 v-if 和 v-for 用在一起 |
写计算属性或将v-if 写在外层 | |
为组件样式设置作用域 | 使用scoped,会在元素上自动添加一个hash值 | |
组件文件名 | my-component.vue、MyComponent.vue | |
基础组件 | 展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App 或 V | BaseButton |
紧密耦合的组件名 | 和父组件紧密耦合的子组件应该以父组件名作为前缀命名 | TodoList.vue、 TodoListItem.vue、TodoListItemButton.vue |
组件名取名 | 应该以高级别的 (通常是一般化描述的) 单词开头,以描述性的修饰词结尾 | SearchButtonClear.vue、SearchButtonRun.vue |
自闭合组件 | 自闭合组件表示没有内容,但DOM模板(html中)不支持 | 在单文件组件、字符串模板和 JSX 中 :<MyComponent/> 在 DOM 模板中 :<my-component></my-component> |
模板中组件名 | 由于 HTML 是大小写不敏感的,在 DOM 模板中必须仍使用 kebab-case | 单文件组件和字符串模板中 :<MyComponent/> 或<my-component></my-component> 在 DOM 模板中 :<my-component></my-component> |
组件名取名完整 | 完整单词,不要省略 | StudentDashboardSettings.vue |
模板中简洁 | 组件模板应该最多只包含简单的表达式,如三目运算 、||,尽可能不要包括方法,因为每次渲染都会调用方法,导致性能不好 | {{ studentCount }}、{{ studentCount || 0 }} {{ showStudentCount ? studentCount : otherAcount }} |
简单的计算属性 | 应该把复杂计算属性分割为尽可能多的更简单的 property | {{ studentCount }}、{{ studentCount || 0 }} {{ showStudentCount ? studentCount : otherAcount }} |
指令缩写 | (用 : 表示 v-bind:、用 @ 表示 v-on: 和用 # 表示 v-slot:) 应该要么都用要么都不用 |
props
props: {
status: { type: String,`
required: true,
validator: function (value) {
return [
'syncing',
'synced',
'version-conflict',
'error'
].indexOf(value) !== -1
}
}
} ;
v-for
<ul>
<li
v-for="todo in todos"
:key="todo.id"
>
{{ todo.text }}
</li>
</ul>
变量名称
重点:见名知意
1、不要使用简单的 data、key、value、param、index、a1、a2、foo、bar等,要让人一眼就看懂
2、如果变量只使用一次,可以直接用不定义,除非是想要通过名字来解释变量的作用,比如多个条件判断。
变量类型 | 建议 | 举例 |
---|---|---|
字符串 | 不要使用text结尾 | daysSinceCreation、daysOfOneMonth、timesOfRequestUser、pickedTimestamp |
数字 | 以count、number结尾 | awardCount、monthCount、winningNumber |
布尔值 | 以can、has、is、need + 名词+形容词、动词、名词 | isMaxinumNumber、isShowDialog、isPageLoaded、hasErrorInReuestList 、canOpenDoor |
数组 | 以list、params等结尾,不要动词开头 | studentInfoList、permissionParams |
对象 | 如果属性少,直接用属性名,比如yearMonth,属性太多就以info结尾 ,不要动词开头 | yearMonth、pickedYearMonth、studentInfo |
方法 | 以i动词开头,如get、check、send、init、login、add 等 | getStudentInfo、getYearMonthWithTimestamp |
常量 | 大写 | const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000; |
常量 | 对象,key 也需要大写 | export const TIME_DETAIL = { MONTH: 12, DAYS: 30 } |
解释性变量 | 不要使用简单的 data、key、value、param、index、a1、a2、foo、bar等 | v-for="(button, buttonIndex) in buttonList" |
不添加不必要的上下文 | type Car = { make: string; model: string; } | |
使用默认变量替代短路运算或条件 | function loadPages(loadCount: number = 10) {} |
函数
函数参数
两个以下最理想,多个需要考虑是否重构
单一性
不好的:
function emailClients(clients: Client) {
clients.forEach((client) => {
const clientRecord = database.lookup(client);
if (clientRecord.isActive()) {
email(client);
}
});
}
好的:
function emailClients(clients: Client) {
clients.filter(isActiveClient).forEach(email);
}
function isActiveClient(client: Client) {
const clientRecord = database.lookup(client);
return clientRecord.isActive();
}
函数名称应该说明它要做什么
addMonthToDate、getUserinfoWithUserAccount
避免冗余代码
写成公共方法或者 class、dont repeat youself
使用 Object.assign 设置默认对象或者解构
type MenuConfig = { title?: string, body?: string, buttonText?: string, cancellable?: boolean };
function createMenu(config: MenuConfig) {
const menuConfig = Object.assign({
title: 'Foo',
body: 'Bar',
buttonText: 'Baz',
cancellable: true
}, config);
// ...
}
createMenu({ body: 'Bar' });
type MenuConfig = { title?: string, body?: string, buttonText?: string, cancellable?: boolean };
function createMenu({ title = 'Foo', body = 'Bar', buttonText = 'Baz', cancellable = true }: MenuConfig) {
// ...
}
createMenu({ body: 'Bar' });
不要使用标记位做为函数参数
标记位是告诉你的用户这个函数做了不只一件事情。 函数应该只做一件事情。 如果你的函数因为一个布尔值 出现不同的代码路径, 请拆分它们。
不好的:
function createFile(name: string, temp: boolean) {
if (temp) {
fs.create(`./temp/${name}`);
} else {
fs.create(name);
}
}
好的:
function createTempFile(name: string) {
createFile(`./temp/${name}`);
}
function createFile(name: string) {
fs.create(name);
}
尽量避免产生闭包
let name = 'Robert C. Martin';
function toBase64() {
name = btoa(name);
}
toBase64();
function toBase64(studentTipList = []) {
let studentTipInfo = {};
studentList.forEach((studentInfo, studentIndex) => {
studentTipInfo[`${studentInfo}Tips`] = ...
})
}
}
避免副作用
尽量不要修改输入对象
不好的:
function addItemToCart(cart: CartItem[], item: Item): void {
cart.push({ item, date: Date.now() });
};
好的:
function addItemToCart(cart: CartItem[], item: Item): CartItem[] {
return [...cart, { item, date: Date.now() }];
};
不好的:
const currentMonth: Month = getMonthWithTimestamp();
let pickedMonth: Month = currentMonth;
好的:
const currentMonth: Month = getMonthWithTimestamp();
let pickedMonth: Month = { ...currentMonth};
不要使用过程式编程
不要使用 for、for in、for of、while 这些过程式编程,因为需要不停得维护变量。
封装条件语句
不好的:
if (subscription.isTrial || account.balance > 0) {
// ...
}
好的:
function canActivateService(subscription: Subscription, account: Account) {
return subscription.isTrial || account.balance > 0
}
if (canActivateService(subscription, account)) {
// ...
}
正面条件
function isEmailUsed(email): boolean {
// ...
}
if (!isEmailUsed(node)) {
// ...
}
合理使用对象
不好的
let year:numebr = null
let month:numebr = null
let day:numebr = null
好的·
interface YearMonthDay {
year: number;
month: number;
day: number;
}
let yearMonthDay: YearMonthDay = {
year: null,
month: null,
day: null,
};
网友评论