可以参看以下这篇文档:https://cn.vuejs.org/v2/style-guide/index.html
一、四个优先级
这篇文章将命名规则分成四个等级:
- 优先级 A:必要的
- 优先级 B:强烈推荐
- 优先级 C:推荐
- 优先级 D:谨慎使用
优先级 A:必要的
这些规则会帮你规避错误,所以学习并接受它们带来的全部代价吧。这里面可能存在例外,但应该非常少,且只有你同时精通 JavaScript 和 Vue 才可以这样做。
优先级 B:强烈推荐
这些规则能够在绝大多数工程中改善可读性和开发体验。即使你违反了,代码还是能照常运行,但例外应该尽可能少且有合理的理由
优先级 C:推荐
当存在多个同样好的选项,选任意一个都可以确保一致性。在这些规则里,我们描述了每个选项并建议一个默认的选择。也就是说只要保持一致且理由充分,你可以随意在你的代码库中做出不同的选择。请务必给出一个好的理由!通过接受社区的标准,你将会:
- 训练你的大脑,以便更容易的处理你在社区遇到的代码;
- 不做修改就可以直接复制粘贴社区的代码示例;
- 能够经常招聘到和你编码习惯相同的新人,至少跟 Vue 相关的东西是这样的
优先级 D:谨慎使用
有些 Vue 特性的存在是为了照顾极端情况或帮助老代码的平稳迁移。当被过度使用时,这些特性会让你的代码难于维护甚至变成 bug 的来源。这些规则是为了给有潜在风险的特性敲个警钟,并说明它们什么时候不应该使用以及为什么
二、优先级 A:必要的(规避错误)
组件名为多个单词
- 组件名应该始终是多个单词的,根组件 App 以及
<transition>
、<component>
之类的 Vue 内置组件除外 - 这样做可以避免跟现有的以及未来的 HTML 元素相冲突,因为所有的 HTML 元素名称都是单个单词的
组件数据
- 组件的 data 必须是一个函数
- 当在组件中使用 data property 的时候 (除了 new Vue 外的任何地方),它的值必须是返回一个对象的函数
Prop 定义
- Prop 定义应该尽量详细
- 在你提交的代码中,prop 的定义应该尽量详细,至少需要指定其类型
- 细致的 prop 定义有两个好处:
- 它们写明了组件的 API,所以很容易看懂组件的用法;
- 在开发环境下,如果向一个组件提供格式不正确的 prop,Vue 将会告警,以帮助你捕获潜在的错误来源
// 好例子!
props: {
status: {
type: String,
required: true,
validator: function (value) {
return [
'syncing',
'synced',
'version-conflict',
'error'
].indexOf(value) !== -1
}
}
}
为 v-for
设置键值
- 总是用
key
配合v-for
- 在组件上总是必须用
key
配合v-for
,以便维护内部组件及其子树的状态。甚至在元素上维护可预测的行为,比如动画中的对象固化 (object constancy),也是一种好的做法// 好例子!
<ul>
<li
v-for="todo in todos"
:key="todo.id"
>
{{ todo.text }}
</li>
</ul>
避免 v-if
和 v-for
用在一起
- 永远不要把
v-if
和v-for
同时用在同一个元素上 ```vue // 好例子!- {{ user.name }}
- {{ user.name }}
<a name="qlpSU"></a>
### 为组件样式设置作用域
- 对于应用来说,顶级 App 组件和布局组件中的样式可以是全局的,但是其它所有组件都应该是有作用域的
- 这条规则只和单文件组件有关。你不一定要使用 scoped attribute。设置作用域也可以通过 CSS Modules,那是一个基于 class 的类似 BEM 的策略,当然你也可以使用其它的库或约定
- 不管怎样,对于组件库,我们应该更倾向于选用基于 class 的策略而不是 scoped attribute
- 这让覆写内部样式更容易:使用了常人可理解的 class 名称且没有太高的选择器优先级,而且不太会导致冲突。
```vue
// 好例子!
<template>
<button class="button button-close">X</button>
</template>
<!-- 使用 `scoped` attribute -->
<style scoped>
.button {
border: none;
border-radius: 2px;
}
.button-close {
background-color: red;
}
</style>
<template>
<button :class="[$style.button, $style.buttonClose]">X</button>
</template>
<!-- 使用 CSS Modules -->
<style module>
.button {
border: none;
border-radius: 2px;
}
.buttonClose {
background-color: red;
}
</style>
<template>
<button class="c-Button c-Button--close">X</button>
</template>
<!-- 使用 BEM 约定 -->
<style>
.c-Button {
border: none;
border-radius: 2px;
}
.c-Button--close {
background-color: red;
}
</style>
私有 property 名
- 使用模块作用域保持不允许外部访问的函数的私有性。如果无法做到这一点,就始终为插件、混入等不考虑作为对外公共 API 的自定义私有 property 使用 $ 前缀。并附带一个命名空间以回避和其它作者的冲突 (比如 $_yourPluginName)。
```json
// 好例子
var myGreatMixin = {
// …
methods: {
$_myGreatMixin_update: function () {
} } }// ...
// 甚至更好! var myGreatMixin = { // … methods: { publicMethod() { // … myPrivateFunction() } } } function myPrivateFunction() { // … } export default myGreatMixin
<a name="XHIhf"></a>
## 三、优先级 B 的规则:强烈推荐 (增强可读性)
<a name="0aEx0"></a>
### 组件文件
- 只要有能够拼接文件的构建系统,就把每个组件单独分成文件。
- 当你需要编辑一个组件或查阅一个组件的用法时,可以更快速的找到它。
好例子
components/ |- TodoList.js |- TodoItem.js
components/ |- TodoList.vue |- TodoItem.vue
<a name="hLGDX"></a>
### 单文件组件的大小写
- 单文件组件的文件名应该要么始终是单词大写开头 (PascalCase),要么始终是横线连接 (kebab-case)。
- 单词大写开头对于代码编辑器的自动补全最为友好,因为这使得我们在 JS(X) 和模板中引用组件的方式尽可能的一致。然而,混用文件命名方式有的时候会导致大小写不敏感的文件系统的问题,这也是横线连接命名同样完全可取的原因。
好例子
components/ |- MyComponent.vue
components/ |- my-component.vue
<a name="pNuMD"></a>
### 基础组件名
- 应用特定样式和约定的基础组件 (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App 或 V。
好例子
components/ |- BaseButton.vue |- BaseTable.vue |- BaseIcon.vue
components/ |- AppButton.vue |- AppTable.vue |- AppIcon.vue
components/ |- VButton.vue |- VTable.vue |- VIcon.vue
<a name="6VWgV"></a>
### 单例组件名
- 只应该拥有单个活跃实例的组件应该以 The 前缀命名,以示其唯一性
- 这不意味着组件只可用于一个单页面,而是每个页面只使用一次。这些组件永远不接受任何 prop,因为它们是为你的应用定制的,而不是它们在你的应用中的上下文。如果你发现有必要添加 prop,那就表明这实际上是一个可复用的组件,只是目前在每个页面里只使用一次
好例子!
components/ |- TheHeading.vue |- TheSidebar.vue
<a name="BQAkW"></a>
### 紧密耦合的组件名
- 和父组件紧密耦合的子组件应该以父组件名作为前缀命名
- 如果一个组件只在某个父组件的场景下有意义,这层关系应该体现在其名字上。因为编辑器通常会按字母顺序组织文件,所以这样做可以把相关联的文件排在一起
好例子!
components/ |- TodoList.vue |- TodoListItem.vue |- TodoListItemButton.vue
components/ |- SearchSidebar.vue |- SearchSidebarNavigation.vue
<a name="eKILO"></a>
### 组件名中的单词顺序
- 组件名应该以高级别的 (通常是一般化描述的) 单词开头,以描述性的修饰词结尾
好例子!
components/ |- SearchButtonClear.vue |- SearchButtonRun.vue |- SearchInputQuery.vue |- SearchInputExcludeGlob.vue |- SettingsCheckboxTerms.vue |- SettingsCheckboxLaunchOnStartup.vue
<a name="zuKaL"></a>
### 自闭合组件
- 在单文件组件、字符串模板和 JSX 中没有内容的组件应该是自闭合的——但在 DOM 模板里永远不要这样做。
- 自闭合组件表示它们不仅没有内容,而且刻意没有内容。其不同之处就好像书上的一页白纸对比贴有“本页有意留白”标签的白纸。而且没有了额外的闭合标签,你的代码也更简洁。
- 不幸的是,HTML 并不支持自闭合的自定义元素——只有官方的“空”元素。所以上述策略仅适用于进入 DOM 之前 Vue 的模板编译器能够触达的地方,然后再产出符合 DOM 规范的 HTML。
```vue
// 好例子!
<!-- 在单文件组件、字符串模板和 JSX 中 -->
<MyComponent/>
<!-- 在 DOM 模板中 -->
<my-component></my-component>
模板中的组件名大小写
- 对于绝大多数项目来说,在单文件组件和字符串模板中组件名应该总是 PascalCase 的——但是在 DOM 模板中总是 kebab-case 的
- PascalCase 相比 kebab-case 有一些优势:
- 编辑器可以在模板里自动补全组件名,因为 PascalCase 同样适用于 JavaScript。
<MyComponent>
视觉上比<my-component>
更能够和单个单词的 HTML 元素区别开来,因为前者的不同之处有两个大写字母,后者只有一个横线- 如果你在模板中使用任何非 Vue 的自定义元素,比如一个 Web Component,PascalCase 确保了你的 Vue 组件在视觉上仍然是易识别的
- 不幸的是,由于 HTML 是大小写不敏感的,在 DOM 模板中必须仍使用 kebab-case。
- 还请注意,如果你已经是 kebab-case 的重度用户,那么与 HTML 保持一致的命名约定且在多个项目中保持相同的大小写规则就可能比上述优势更为重要了。在这些情况下,在所有的地方都使用 kebab-case 同样是可以接受的
```vue
// 好例子
<a name="1ozec"></a>
### JS/JSX 中的组件名大小写
- JS/JSX 中的组件名应该始终是 PascalCase 的,尽管在较为简单的应用中只使用 Vue.component 进行全局组件注册时,可以使用 kebab-case 字符串
```vue
// 好例子
Vue.component('MyComponent', {
// ...
})
Vue.component('my-component', {
// ...
})
import MyComponent from './MyComponent.vue'
export default {
name: 'MyComponent',
// ...
}
完整单词的组件名
- 组件名应该倾向于完整单词而不是缩写
- 编辑器中的自动补全已经让书写长命名的代价非常之低了,而其带来的明确性却是非常宝贵的。不常用的缩写尤其应该避免
// 好例子!
components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue
「@浪里淘沙的小法师」