# @h3/eslint-config-vue
维护人:木木(linqh@authine.com)
- 安装
- 规则
- vue/attribute-hyphenation
- vue/html-self-closing
- vue/max-attributes-per-line
- vue/no-multi-spaces
- require-default-prop
- vue/attributes-order
- vue/order-in-components
- vue/this-in-template
- vue/array-bracket-spacing
- vue/arrow-spacing
- vue/block-spacing
- vue/component-name-in-template-casing
- vue/eqeqeq
- vue/key-spacing
- vue/object-curly-spacing
- vue/require-direct-export
- vue/space-infix-ops
- vue/v-on-function-call
- vue/valid-v-slot
# 该规则包基于esLint-plugin-vue Rules定制,默认继承strongly-recommended
及Essential
的规则,大部分规则格式都可以支持--fix
# 安装
npm install --save-dev @h3/eslint-config-vue
# 规则
# vue/attribute-hyphenation
# 规则
"vue/attribute-hyphenation": ["error", "never", {
"ignore": ['data-', 'aria-', 'slot-scope']
}]
2
3
# 介绍
除了 ignore 数组里面提供的字符串,其他属性必须以驼峰法来书写
# Code Demo
<template>
<!-- ✔ GOOD -->
<MyComponent myProp="prop" />
<MyComponent data-id="prop" />
<MyComponent aria-role="button" />
<MyComponent slot-scope="prop" />
<!-- ✘ BAD -->
<MyComponent my-prop="prop" />
</template>
2
3
4
5
6
7
8
9
10
# vue/html-self-closing
# 规则
"vue/html-self-closing": ["error", {
"html": {
"void": "always",
"normal": "never",
"component": "always"
},
"svg": "always",
"math": "always"
}]
2
3
4
5
6
7
8
9
# 介绍
原生标签无内容的需要单标签闭合,常规元素不闭合,
自定义组件无内容需要单标签闭合
# Code Demo
// html
<template>
<!-- ✓ GOOD -->
<div />
<img/>
<MyComponent/>
<svg><path d=""/></svg>
<!-- ✗ BAD -->
<div/>
<img>
<MyComponent></MyComponent>
<svg><path d=""></path></svg>
</template>
2
3
4
5
6
7
8
9
10
11
12
13
14
# vue/max-attributes-per-line
# 规则:
"vue/max-attributes-per-line": ["error", {
"singleline": 3,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}]
2
3
4
5
6
7
# 介绍
标签行最多同时存在三个属性,多出要换行,
换行后每行只允许存在一个属性,不允许并排
# Code Demo
<template>
<!-- ✓ GOOD -->
<MyComponent lorem="1"/>
<MyComponent
lorem="1"
ipsum="2"
/>
<MyComponent
lorem="1"
ipsum="2"
dolor="3"
/>
<!-- ✗ BAD -->
<MyComponent lorem="1" ipsum="2" a="3" faer="2342"/>
<MyComponent
lorem="1" ipsum="2"
/>
<MyComponent
lorem="1" ipsum="2"
dolor="3"
/>
</template>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# vue/no-multi-spaces
# 规则
"vue/no-multi-spaces": ["error", {
"ignoreProperties": true
}]
2
3
# 介绍
多行不允许任意空格或者多个空格,属性除外
# Code Demo
<template>
<!-- ✓ GOOD -->
<i
:class="{
'fa-angle-up' : isExpanded,
'fa-angle-down' : !isExpanded,
}"
/>
</template>
2
3
4
5
6
7
8
9
10
# require-default-prop
# 规则
"require-default-prop": "off"
# 介绍
关闭所有 props
声明类型都需要定义默认值
# Code Demo
<script>
export default {
props: {
/* ✓ GOOD */
a: {
type: Number,
required: true
},
b: {
type: Number,
default: 0
},
c: {
type: Number,
default: 0,
required: false
},
d: {
type: Boolean, // Boolean is the only type that doesn't require default
},
/* ✗ BAD --- 关闭后可以了*/
e: Number,
f: [Number, String],
g: [Boolean, Number],
j: {
type: Number
},
i: {
type: Number,
required: false
}
}
}
</script>
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
# vue/attributes-order
# 规则
"vue/attributes-order": ["error", {
"order": [
"GLOBAL",
"DEFINITION",
"LIST_RENDERING",
"CONDITIONALS",
"RENDER_MODIFIERS",
"UNIQUE",
"TWO_WAY_BINDING",
"OTHER_DIRECTIVES",
"OTHER_ATTR",
"CONTENT",
"EVENTS"
]
}]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 介绍
props
在标签的先后顺序需要遵循格式
# Code Demo
/<template>
<!-- ✓ GOOD -->
<div
id="uniqueID"
is="header"
v-for="item in items"
v-if="!visible"
v-once
ref="header"
v-model="headerData"
my-prop="prop"
v-text="textContent"
@click="functionCall"
>
</div>
<div
v-for="item in items"
v-if="!visible"
prop-one="prop"
:prop-two="prop"
prop-three="prop"
@click="functionCall"
v-text="textContent">
</div>
<div
prop-one="prop"
:prop-two="prop"
prop-three="prop">
</div>
<!-- ✗ BAD -->
<div
ref="header"
v-for="item in items"
v-once
id="uniqueID"
v-model="headerData"
my-prop="prop"
v-if="!visible"
is="header"
@click="functionCall"
v-text="textContent">
</div>
</template>
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
# vue/order-in-components
# 规则
"vue/order-in-components": ["error", {
"order": [
"el",
"name",
"parent",
"functional",
["delimiters", "comments"],
["components", "directives", "filters"],
"extends",
"mixins",
"inheritAttrs",
"model",
["props", "propsData"],
"fetch",
"asyncData",
"data",
"computed",
"watch",
"LIFECYCLE_HOOKS",
"methods",
"head",
["template", "render"],
"renderError"
]
}]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 介绍
组件内的代码顺序需要按照规则
# Code Demo
没有代码演示,自行脑补
# vue/this-in-template
# 规则
"vue/this-in-template": ["error", "never"]
# 介绍
模板的值不允许出现 this
# Code Demo
<template>
<!-- ✓ GOOD -->
<a :href="url">
{{ text }}
</a>
<!-- ✗ BAD -->
<a :href="this.url">
{{ this.text }}
</a>
</template>
2
3
4
5
6
7
8
9
10
11
# vue/array-bracket-spacing
# 规则
"vue/array-bracket-spacing": "error"
# 介绍
数组或者数组解构的展示的值需要有空格
# Code Demo
效果和 eslint 的对应规则一致,只是该规则对 Vue 的template
也处理
# vue/arrow-spacing
# 规则
"vue/arrow-spacing": "error"
# 介绍
箭头函数两端需要空格
# Code Demo
效果和 eslint 的对应规则一致,只是该规则对 Vue 的template
也处理
# vue/block-spacing
# 规则
"vue/block-spacing": "error"
# 介绍
函数块需要有空格
# Code Demo
效果和 eslint 的对应规则一致,只是该规则对 Vue 的template
也处理
# vue/component-name-in-template-casing
# 规则
"vue/component-name-in-template-casing": ["error", "kebab-case"]
# 介绍
注册的组件在template
中必须kebad-case
的风格展示
# Code Demos
<template>
<!-- ✓ GOOD -->
<cool-component />
<!-- ✗ BAD -->
<CoolComponent />
<coolComponent />
<Cool-component />
<!-- ignore -->
<unregistered-component />
<UnregisteredComponent />
</template>
<script>
export default {
components: {
CoolComponent
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# vue/eqeqeq
# 规则
"vue/eqeqeq": "error"
# 介绍
模板中的必须使用全等(===
),不可以==
# Code Demo
自行脑补
# vue/key-spacing
# 规则
"vue/key-spacing": ['error', {
align: {
beforeColon: false,
afterColon: true,
},
}]
2
3
4
5
6
7
# 介绍
对象内的键值对基于冒号对齐,冒号左边紧跟,右边允许空格
# Code Demo
规则和 eslint 的效果一样,只是这个作用于template
# vue/object-curly-spacing
# 规则
"vue/object-curly-spacing": "error"
# 介绍
对对象的括号的调整
# Code Demo
规则和 eslint 的效果一样,只是这个作用于template
# vue/require-direct-export
# 规则
"vue/require-direct-export": "off"
# 介绍
在组件内遵循官方的写法,export default {}
而非先保存,最后再导出。
关闭后就不限定只有这种写法
# Code Demo
<script>
/* ✓ GOOD */
export default {
name: 'ComponentA',
data() {
return {
state: 1
}
}
}
</script>
/* 关闭后该写法也支持,ts 的 extend 也支持
<script>
const ComponentA = {
name: 'ComponentA',
data() {
return {
state: 1
}
}
}
export default ComponentA
</script>
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
# vue/space-infix-ops
# 规则
"vue/space-infix-ops":"error"
# 介绍
运算符两边填充空格
# Code Demo
规则和 eslint 的效果一样,只是这个作用于template
# 规则
# vue/v-on-function-call
"vue/v-on-function-call": ["error", "never"]
# 介绍
绑定函数的时侯,无入参禁止使用()
# Code Demo
<template>
<!-- ✓ GOOD -->
<button v-on:click="closeModal">
Close
</button>
<!-- ✗ BAD -->
<button v-on:click="closeModal()">
Close
</button>
</template>
2
3
4
5
6
7
8
9
10
11
12
# vue/valid-v-slot
# 规则
"vue/valid-v-slot": "error"
# 介绍
校验v-slot
是否遵循官方的标准写法
# Code Demo
<template>
<!-- ✓ GOOD -->
<my-component v-slot="data">
{{data}}
</my-component>
<my-component>
<template v-slot:default>
default
</template>
<template v-slot:one>
one
</template>
<template v-slot:two>
two
</template>
</my-component>
<!-- ✗ BAD -->
<div v-slot="data">
{{data}}
</div>
<div>
<template v-slot:one>
one
</template>
</div>
<my-component v-slot:one="data">
{{data}}
</my-component>
<my-component v-slot="data">
{{data}}
<template v-slot:one>
one
</template>
</my-component>
<my-component v-slot:one v-slot:two>
one and two
</my-component>
<my-component>
<template v-slot:one>
one 1
</template>
<template v-slot:one>
one 2
</template>
</my-component>
<my-component>
<template v-slot:[data]="data">
dynamic?
</template>
</my-component>
<my-component v-slot.mod="data">
{{data}}
</my-component>
<my-component v-slot>
content
</my-component>
</template>
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63