[TOC]

1、组件名多单词(完整单词),每个组件单独分为文件,PascalCase风格命名

1
2
3
4
5
6
7
8
9
10
11
12
13
<TodoList>

components/ //以一般化描述单词开头,以修饰词结尾,方便查找组件
|- TodoList.vue
|- TodoItem.vue
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue

ps:
单例组件:每个页面只使用一次:+The前缀
紧密耦合的组件:组件只在某个父组件的场景下有意义:+父组件名当前缀
自闭合组件:表示它们不仅没有内容,而且刻意没有内容:<MyComponent/>

2、data值返回函数

1
2
3
4
5
6
data: function () {
return {
listTitle: '',
todos: []
}
}

3、prop 的定义应该尽量详细,至少需要指定其类型,camelCase风格命名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//组件在HTML中是xxx-xxx 其他地方定义是xxxXxx
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number, Boolean, Array, Object, Function, Promise...],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})

ps:
1、这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data property 并将这个 prop 用作其初始值:
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
2、这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}

4、不要把 v-if 和 v-for 同时用在同一个元素上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
为了过滤一个列表中的项目 (比如 v-for="user in users" v-if="user.isActive")。在这种情形下,请将 users 替换为一个计算属性 (比如 activeUsers),让其返回过滤后的列表。
<ul>
<li
v-for="user in activeUsers"
:key="user.id"
>
{{ user.name }}
</li>
</ul>

computed: {
activeUsers: function () {
return this.users.filter(function (user) {
return user.isActive
})
}
}

5、为组件样式或实例property设置作用域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<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>

你可能会在很多组件里用到数据/实用工具,但是不想污染全局作用域。这种情况下,你可以通过在原型上定义它们使其在每个 Vue 的实例中可用
Vue.prototype.$appName = 'My App'
这样 $appName 就在所有的 Vue 实例中可用了,甚至在实例被创建之前就可以。如果我们运行:
new Vue({
beforeCreate: function () {
console.log(this.$appName)
}
})

6、组件/实例的选项的顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
这是我们推荐的组件选项默认顺序。它们被划分为几大类,所以你也能知道从插件里添加的新 property 应该放到哪里。

1. **副作用** (触发组件外的影响)
- `el`
2. **全局感知** (要求组件以外的知识)
- `name`
- `parent`
3. **组件类型** (更改组件的类型)
- `functional`
4. **模板修改器** (改变模板的编译方式)
- `delimiters`
- `comments`
5. **模板依赖** (模板内使用的资源)
- `components`
- `directives`
- `filters`
6. **组合** (向选项里合并 property)
- `extends`
- `mixins`
7. **接口** (组件的接口)
- `inheritAttrs`
- `model`
- `props`/`propsData`
8. **本地状态** (本地的响应式 property)
- `data`
- `computed`
9. **事件** (通过响应式事件触发的回调)
- `watch`
- 生命周期钩子 (按照它们被调用的顺序)
- `beforeCreate`
- `created`
- `beforeMount`
- `mounted`
- `beforeUpdate`
- `updated`
- `activated`
- `deactivated`
- `beforeDestroy`
- `destroyed`
10. **非响应式的 property** (不依赖响应系统的实例 property)
- `methods`
11. **渲染** (组件输出的声明式描述)
- `template`/`render`
- `renderError`

7、元素 attribute 的顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
这是我们为组件选项推荐的默认顺序。它们被划分为几大类,所以你也能知道新添加的自定义 attribute 和指令应该放到哪里。

1. **定义** (提供组件的选项)
- `is`
2. **列表渲染** (创建多个变化的相同元素)
- `v-for`
3. **条件渲染** (元素是否渲染/显示)
- `v-if`
- `v-else-if`
- `v-else`
- `v-show`
- `v-cloak`
4. **渲染方式** (改变元素的渲染方式)
- `v-pre`
- `v-once`
5. **全局感知** (需要超越组件的知识)
- `id`
6. **唯一的 attribute** (需要唯一值的 attribute)
- `ref`
- `key`
7. **双向绑定** (把绑定和事件结合起来)
- `v-model`
8. **其它 attribute** (所有普通的绑定或未绑定的 attribute)
9. **事件** (组件事件监听器)
- `v-on`
10. **内容** (覆写元素的内容)
- `v-html`
- `v-text`

8、一组 v-if + v-else 的元素类型相同,最好使用 key (比如两个 div 元素)。

1
2
3
4
5
6
7
8
9
10
11
12
<div
v-if="error"
key="search-status"
>
错误:{{ error }}
</div>
<div
v-else
key="search-results"
>
{{ results }}
</div>

9、元素选择器应该避免在 scoped 中出现。

1
2
3
4
5
在 scoped 样式中,类选择器比元素选择器更好,因为大量使用元素选择器是很慢的。

标识选择器:id
类选择器:class
元素(属性)选择器:div p button...