书写规范
定义好格式与规范 是 写代码,做项目的基础; (格式与规范要禁得起验证!)
利于定义软件组件之间的接口,利于深入了解现存的js库的行为;
利于通过动态加载的组件来减少命名冲突,类型选择系统;
文件命名规范
1. 全部采用小写方式, 以下划线分隔
eg: my-project-name
HTML书写规范
<!--
原则: 任何时候都要用 尽量小的复杂度和尽量少的标签 来解决问题
1. 缩进使用soft tab(4个空格);
2. 嵌套的节点应该缩进;
3. 在属性上,使用双引号,不要使用单引号;
4. 属性名全小写,用中划线做分隔符;
5. 不要在自动闭合标签结尾处使用斜线;
6. 不要忽略可选的关闭标签,例:</li> 和 </body>。
7. 应在html标签上加上lang属性。这会给语音工具和翻译工具帮助,告诉它们应当怎么去发音和翻译
8. 属性应该按照特定的顺序出现以保证易读性;
class
id
name
data-*
src, for, type, href, value , max-length, max, min, pattern
placeholder, title, alt
aria-*, role
required, readonly, disabled
9. 在JS文件中生成标签让内容变得更难查找,更难编辑,性能更差(jsx除外)
10. 在编写HTML代码时,需要尽量避免多余的父节点;很多时候,需要通过迭代和重构来使HTML变得更少。
-->
<!DOCTYPE html>
<html lang='zh'>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Page title</title>
<link rel="stylesheet" href="code_guide.css">
<style></style>
</head>
<body>
<img src="images/company_logo.png" alt="Company">
<h1 class="hello-world">Hello, world!</h1>
<input type="checkbox" value="1" checked>
<script></script>
</body>
</html>
CSS书写规范
<!--
1. 使用soft tab(4个空格);
2. 每个属性声明末尾都要加分号;
3. 注释统一用'/* */';
4. 最外层统一使用双引号;
5. 尽量将媒体查询的规则靠近与他们相关的规则;
6. 属性顺序:
1. Positioning Model 布局方式、位置,eg:position, top, z-index, display, float等
2. Box Model 盒模型,eg:width, height, padding, margin,border, overflow
3. Typographic 文本排版,eg:font, line-height, text-align
4. Visual 视觉外观,eg:color, background, list-style, transform, animation
-->
/* class用 - 连接 尽量语义化 */
/* 属性能简写就简写 */
/* 颜色16进制能缩写就缩写 */
/* 去掉小数点前的0 */
/* 用 border: 0; 代替 border: none; */
/* 不轻易使用id */
/* id采用驼峰式命名 */
/* scss中的变量、函数、混合、placeholder采用驼峰式命名 */
.element,
.top-banner {
/* position */
position: absolute;
top: 10px; /* 10px */
left: 10px;
width: 50px;
height: 50px;
border-radius: 10px;
background-color: #012;
}
@media (min-width: 480px) {
.element {
}
}
@if {
} @else {
}
JavaScript规范
注意 JSDoc 的书写规范,可以让自己的代码更加富有可读性和规范性。
ESLint
console.log(111);
/* eslint-disable no-console, no-alert */
console.log(123);
/* eslint-enable */
console.log(123);
prettier规则
module.exports = {
// 一行最多 80 字符
printWidth: 80,
// 使用 4 个空格缩进
tabWidth: 4,
// 不使用缩进符,而使用空格
useTabs: false,
// 行尾需要有分号
semi: true,
// 使用单引号
singleQuote: true,
// 对象的 key 仅在必要时用引号
quoteProps: 'as-needed',
// jsx 不使用单引号,而使用双引号
jsxSingleQuote: false,
// 末尾不需要逗号
trailingComma: 'none',
// 大括号内的首尾需要空格
bracketSpacing: true,
// jsx 标签的反尖括号需要换行
jsxBracketSameLine: false,
// 箭头函数,只有一个参数的时候,也需要括号
arrowParens: 'always',
// 每个文件格式化的范围是文件的全部内容
rangeStart: 0,
rangeEnd: Infinity,
// 不需要写文件开头的 @prettier
requirePragma: false,
// 不需要自动在文件开头插入 @prettier
insertPragma: false,
// 使用默认的折行标准
proseWrap: 'preserve',
// 根据显示样式决定 html 要不要折行
htmlWhitespaceSensitivity: 'css',
// 换行符使用 lf
endOfLine: 'lf'
};
// 无 BOM UTF-8编码
// 文件结尾处保留一个空行
// 缩进
switch () {
case '1':
// do...
break;
case '2':
// do...
break;
default:
// do...
}
// 二元运算符两侧必须有一个空格,一元运算符与操作对象之间不允许有空格
var a = !boo;
c++;
var b = c + d;
// 代码块起始;关键字之后的空格
if (condition) {
}
while (condition) {
}
(function () {
})();
// 对象属性
var obj = {
a: 1,
b: 2,
c: 3
};
// 函数名
function funcName() {
}
var funcName = function funcName() {
};
funcName();
// 标点符号
callFunc(a, b);
// 括号内
callFunc(param1, param2, param3);
save(this.list[this.indexes[i]]);
needIncream && (variable += increament);
if (num > list.length) {
}
while (len--) {
}
// 数组对象
var arr1 = [];
var arr2 = [1, 2, 3];
var obj1 = {};
var obj2 = {name: 'obj'};
var obj3 = {
name: 'obj',
age: 20,
sex: 1
};
// 换行,每个独立语句结束后必须换行,每行不得超过120个字符
if (user.isAuthenticated()
&& user.isInRole('admin')
&& user.hasAuthority('add-admin')
|| user.hasAuthority('delete-admin')
) {
// Code
}
var result = number1 + number2 + number3
+ number4 + number5;
// 逗号换行
var obj = {
a: 1,
b: 2,
c: 3
};
/**
* @func
* @desc 一个带参数的函数
* @param {string} a - 参数a
* @param {number} b=1 - 参数b默认值为1
* @param {string} c=1 - 参数c有两种支持的取值</br>1—表示x</br>2—表示xx
* @param {object} d - 参数d为一个对象
* @param {string} d.e - 参数d的e属性
* @param {string} d.f - 参数d的f属性
* @param {object[]} g - 参数g为一个对象数组
* @param {string} g.h - 参数g数组中一项的h属性
* @param {string} g.i - 参数g数组中一项的i属性
* @param {string} [j] - 参数j是一个可选参数
*/
function foo(a, b, c, d, g, j) {
...
}
foo(
aVeryVeryLongArgument,
anotherVeryLongArgument,
callback
);
// 不同行为或逻辑的语句集,使用空行隔开,更易阅读
function setStyle(element, property, value) {
if (element == null) {
return;
}
element.style[property] = value;
}
// 较复杂的逻辑条件组合,将每个条件独立一行,逻辑运算符放置在行首进行分隔,或将部分逻辑按逻辑组合进行分隔。
// 建议最终将右括号 ) 与左大括号 { 放在独立一行,保证与 `if` 内语句块能容易视觉辨识。
if (user.isAuthenticated()
&& user.isInRole('admin')
&& user.hasAuthority('add-admin')
|| user.hasAuthority('delete-admin')
) {
// Code
}
// 按一定长度截断字符串,并使用 + 运算符进行连接。
// 分隔字符串尽量按语义进行,如不要在一个完整的名词中间断开。
// 特别的,对于 HTML 片段的拼接,通过缩进,保持和 HTML 相同的结构。
// 使用 + 拼接字符串,如果拼接的全部是 StringLiteral,压缩工具可以对其进行自动合并的优化。所以,静态字符串建议使用 + 拼接。
// 在现代浏览器下,使用 + 拼接字符串,性能较数组的方式要高。
// 如需要兼顾老旧浏览器,应尽量使用数组拼接字符串。
var html = '' // 此处用一个空字符串,以便整个 HTML 片段都在新行严格对齐
+ '<article>'
+ '<h1>Title here</h1>'
+ '<p>This is a paragraph</p>'
+ '<footer>Complete</footer>'
+ '</article>';
// 也可使用数组来进行拼接,相对 `+` 更容易调整缩进。
var html = [
'<article>',
'<h1>Title here</h1>',
'<p>This is a paragraph</p>',
'<footer>Complete</footer>',
'</article>'
];
html = html.join('');
// 当参数过多时,将每个参数独立写在一行上,并将结束的右括号 ) 独立一行。
// 所有参数必须增加一个缩进。
foo(
aVeryVeryLongArgument,
anotherVeryLongArgument,
callback
);
// 也可以按逻辑对参数进行组合。
// 最经典的是 baidu.format 函数,调用时将参数分为“模板”和“数据”两块
baidu.format(
dateFormatTemplate,
year, month, date, hour, minute, second
);
// 当函数调用时,如果有一个或以上参数跨越多行,应当每一个参数独立一行。
// 这通常出现在匿名函数或者对象初始化等作为参数时,如 `setTimeout` 函数等。
setTimeout(
function () {
alert('hello');
},
200
);
order.data.read(
'id=' + me.model.id,
function (data) {
me.attchToModel(data.result);
callback();
},
300
);
// 链式调用较长时采用缩进进行调整。
$('#items')
.find('.selected')
.highlight()
.end();
// 三元运算符由3部分组成,因此其换行应当根据每个部分的长度不同,形成不同的情况。
var result = thisIsAVeryVeryLongCondition
? resultA : resultB;
var result = condition
? thisIsAVeryVeryLongResult
: resultB;
// 数组和对象初始化的混用,严格按照每个对象的 `{` 和结束 `}` 在独立一行的风格书写。
var array = [
{
// ...
},
{
// ...
}
];
// 函数定义结束不允许添加分号,如果是函数表达式,分号是不允许省略的
// 立即执行函数(IIFE)
var task = (function () {
// Code
return result;
})();
// 变量:驼峰命名法;常量:全大写,下划线连接;函数:驼峰命名法; 类: Pascal命名法
// 函数名 使用 动宾短语
// boolean 类型的变量使用 is 或 has 开头
// Promise对象 用 动宾短语的进行时 表达
// 避免使用 /*...*/ 这样的多行注释。有多行注释内容时,使用多个单行注释
// 在 Equality Expression 中使用类型严格的 ===。仅当判断 null 或 undefined 时,允许使用 == null
// 数组非空
// good
if (collection.length) {
// ......
}
// null 或 undefined
// good
if (noValue == null) {
// ......
}
// bad
if (noValue === null || typeof noValue === 'undefined') {
// ......
}
// 对于相同变量或表达式的多值条件,用 switch 代替 if
// 如果函数或全局中的 else 块后没有任何语句,可以删除 else
// 不要在循环体中包含函数表达式,事先将函数提取到循环体外
// good
function clicker() {
// ......
}
for (var i = 0, len = elements.length; i < len; i++) {
var element = elements[i];
addListener(element, 'click', clicker);
}
// 类型检测
// string
typeof variable === 'string'
// number
typeof variable === 'number'
// boolean
typeof variable === 'boolean'
// Function
typeof variable === 'function'
// Object
typeof variable === 'object'
// RegExp
variable instanceof RegExp
// Array
variable instanceof Array
// null
variable === null
// null or undefined
variable == null
// undefined
typeof variable === 'undefined'
// 转换string
num + '';
// 转换成 number 时,通常使用 +
+str
// string 转换成 number,要转换的字符串结尾包含非数字并期望忽略时,使用 parseInt
// 使用 parseInt 时,必须指定进制
var width = '200px';
parseInt(width, 10);
// 转换成boolean时, 使用!!
var num = 3.14;
!!num;
// number 去除小数点,使用 Math.floor / Math.round / Math.ceil
Math.ceil(num);
// 字符串开头和结束使用单引号 '
// 清空数组使用 .length = 0
// 一个函数的长度控制在 50 行以内
// 一个函数的参数控制在 6 个以内
VSCode直接下载eslint插件
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
module.exports = {
// 以当前目录为根目录,不再向上查找 .eslintrc.js
root: true,
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 2019,
// ECMA modules 模式
sourceType: 'module',
ecmaFeatures: {
// 不允许 return 语句出现在 global 环境下
globalReturn: false,
// 开启全局 strict 模式
impliedStrict: true,
jsx: true
},
// 即使没有babelrc配置文件, 也使用 babel-eslint 来解析
requireConfigFile: false,
// 仅允许 import export 语句出现在模块的顶层
allowImportExportEverywhere: false
},
extends: '',
plugins: [
'html'
],
env: {
browser: true,
node: true,
commonjs:true,
es6: true
},
rules: {
// setter 必须有对应的 getter,getter 可以没有对应的 setter
'accessor-pairs': [
'error',
{
setWithoutGet: true,
getWithoutSet: false
}
],
// 数组的方法除了 forEach 之外,回调函数必须有返回值
'array-callback-return': 'error',
// 将var定义的变量视为块作用域, 禁止在块外使用(off, 禁止使用var)
'block-scoped-var': 'off',
// 变量名必须是camelCase风格的(关)
'camelcase': 'off',
// 注释的首字母必须大写(关)
'capitalized-comments': 'off',
// 在类的非静态方法中,必须存在对this的引用(关)
'class-methods-use-this': 'off',
// 禁止函数的循环复杂度超过20
'complexity': [
'error',
{
max: 20
}
],
// 禁止函数在不同分支返回不同类型的值(off)@reason 缺少 TypeScript 的支持,类型判断是不准确的
'consistent-return': 'off',
// 限制this的别名
'consistent-this': 'off',
// constructor中必须有super
'constructor-super': 'error',
// switch语句必须有default
'default-case': 'off',
// switch语句中的default必须在最后
'default-case-last': 'error',
// 有默认值的参数必须放在函数参数的末尾 (off)
'default-param-last': 'off',
// 禁止使用foo['bar'], 必须写成 foo.bar (off)
'dot-notation': 'off',
// 必须使用 === 或 !==,禁止使用 == 或 !=
eqeqeq: ['error', 'always'],
// 禁止方向错误的for循环 ??
'for-direction': 'error',
// 函数赋值给变量的时候,函数名必须与变量名一致
'func-name-matching': [
'error',
'always',
{
includeCommonJSModuleExports: false
}
],
// 函数必须有名字(off)
'func-names': 'off',
// 必须只使用函数声明或只使用函数表达式
'func-style': 'off',
// getter 必须有返回值,并且禁止返回空
'getter-return': 'off',
// setter 和 getter必须写在一起
'grouped-accessor-pairs': 'error',
// for in 内部必须有 hasOwnProperty
'guard-for-in': 'error',
// 禁止使用指定的标识符
'id-denylist': 'off',
// 限制变量名长度
'id-length': 'off',
// 限制变量名必须匹配指定的正则表达式
'id-match': 'off',
// 变量必须在定义的时候赋值
'init-declarations': 'off',
// 单行注释必须写在上一行
'line-comment-position': 'off',
// 类的成员之间是否需要空行
'lines-between-class-members': 'off',
// 限制一个文件中类的数量
'max-classes-per-file': 'off',
// 代码块嵌套的深度禁止超过5层
'max-depth': ['error', 5],
// 限制一个文件最多的行数
'max-lines': 'off',
// 限制函数块中的代码行数
'max-lines-per-function': 'off',
// 回调函数嵌套禁止超过3层, 多了请用async await替代
'max-nested-callbacks': ['error', 3],
// 函数的参数禁止超过3个
'max-params': ['error', 3],
// 限制函数块中的语句数量
'max-statements': ['off'],
// 限制一行中的语句数量
'max-statements-per-line': 'off',
// 约束多行注释的格式(能写注释已经很不容易了,不需要限制太多)
'multiline-comment-style': 'off',
// new 后面的类名必须首字母大写
'new-cap': [
'error',
{
newIsCap: true,
capIsNew: false,
properties: true
}
],
// 禁止使用alert
'no-alert': 'off'
// 禁止使用Array构造函数时传入的参数超过一个(参数为一个时表示创建一个指定长度的数组,比较常用)
'no-array-constructor': 'error'
// 禁止将 async 函数作为 new Promise 的回调函数; 出现这种情况时,一般不需要使用 new Promise 实现异步了
'no-async-promise-executor': 'error',
// 禁止将 await 写在循环里, 因为这样就无法同时发送多个异步请求了
'no-await-in-loop': 'off',
// 禁止使用位运算
'no-bitwise': 'off',
// 禁止使用 caller 或 callee
'no-caller': 'error',
// switch 的 case 内有变量定义的时候, 必须使用大括号将case内变成一个代码块
'no-case-declarations': 'error',
// 禁止对已定义的class重新赋值
'no-class-assign': 'error',
// 禁止与负零进行比较
'no-compare-neg-zero': 'error',
// 禁止在测试表达式中使用赋值语句,除非这个赋值语句被括号包起来了
'no-cond-assign': ['error', 'except-parens'],
// 禁止使用console
'no-console': 'off',
// 禁止将常量作为分支条件判断中的测试表达式,但允许作为循环条件判断中的测试表达式
'no-constant-condition': [
'error',
{
checkLoops: false
}
],
// 禁止在构造函数中返回值
'no-constructor-return': 'error',
// 禁止使用continue
'no-continue': 'off',
// 禁止在正则表达式中出现 ctrl 键的 ASCII表示
'no-control-regex': 'off',
// 禁止使用 debugger
'no-debugger': 'error',
// 禁止对一个变量使用 delete
'no-delete-var': 'off',
// 禁止在正则表达式中出现形似除法操作符的开头,如 let a = /=foo/
'no-div-regex': 'off',
// 禁止在函数参数中出现重复名称的参数
'no-dupe-args': 'off',
// 禁止重复定义类的成员
'no-dupe-class-members': 'error',
// 禁止 if else 的条件判断中出现重复的条件
'no-dupe-else-if': 'error',
// 禁止在对象字面量中出现重复的键名
'no-dupe-keys': 'error',
// 禁止在 switch 语句中出现重复测试表达式的 case
'no-duplicate-case': 'error',
// 禁止重复导入模块
'no-duplicate-imports': 'error'
// 禁止在else内使用 return, 必须改为提前结束
'no-else-return': 'off',
// 禁止出现空代码块, 允许 catch 为空代码块
'no-empty': [
'error',
{
allowEmptyCatch: true
}
],
// 禁止在正则表达式中使用空的字符集
'no-empty-character-class': 'error',
// 不允许有空函数(有时需要将一个空函数设置为某个项的默认值)
'no-empty-function': 'off',
// 禁止解构赋值中出现空 {} 或 []
'no-empty-pattern': 'error',
// 禁止使用 foo == null, 必须使用 foo === null
'no-eq-null': 'error',
// 禁止使用 eval
'no-eval': 'error'
// 禁止将catch中的第一个参数error重新赋值
'no-ex-assgin': 'error',
// 禁止修改原生对象
'no-extend-native': 'error',
// 禁止出现没必要的 bind
'no-extra-bind': 'error',
// 禁止不必要的布尔类型转换
'no-extra-boolean-cast': 'error',
// 禁止出现没必要的label
'no-extra-label': 'off',
// switch case内必须有 break, return 或 throw, 空的 case 除外
'no-fallthrouth': 'error',
// 禁止将一个函数声明重新赋值
'no-func-assign': 'error',
// 禁止对全局变量赋值
'no-global-assign': 'error',
// 禁止使用 ~+ 等难以理解的类型转换, 仅允许使用 !!
'no-implicit-coercion': [
'error',
{
allow: ['!!']
}
],
// 禁止在全局作用域下定义变量或声明函数,模块化之后不会出现这种情况
'no-implicit-globals': 'off',
// 禁止在setTimeout 或 setInterval中传入字符串
'no-implied-eval': 'error',
// 禁止对导入的模块进行赋值
'no-import-assign':'error',
// 禁止在代码后添加单行注释
'no-inline-comments': 'off',
// 禁止在if代码块中出现函数声明
'no-inner-declarations': ['error', 'both'],
// 禁止在 regexp构造函数中出现非法的正则表达式
'no-invalid-regexp': 'error',
// 禁止在类之外的地方使用this, 只允许在class中使用this
'no-invalid-this': 'error',
// 禁止使用特殊空白符(比如全角空格),除非是出现在字符串、正则表达式或模板字符串中
'no-irregular-whitespace': [
'error',
{
skipStrings: true,
skipComments: false,
skipRegExps: true,
skipTemplates: true
}
],
// 禁止使用 __iterator__
'no-iterator': 'error',
// 禁止label名称与已定义的变量重复
'no-label-var': 'off',
// 禁止使用label
'no-labels': 'error',
// 禁止使用没必要的 {} 作为代码块
'no-lone-blocks': 'error',
// 禁止 else 中只有一个单独的 if
'no-lonely-if': 'off',
// 禁止在循环内的函数内部出现循环体条件语句中定义的变量(let可以解决这个问题)
'no-loop-func': 'off',
// 禁止使用超出 js 精度范围的数字
'no-loss-of-precision': 'error',
// 禁止使用magic numbers
'no-magic-numbers': 'off',
// 禁止正则表达式中使用肉眼无法区分的特殊字符
'no-misleading-character-class': 'error',
// 禁止连续赋值
'no-multi-assign': 'off',
// 禁止使用 \ 来换行字符串 ??
'no-multi-str': 'error',
// 禁止 if 中有否定的表达式
'no-negated-condition': 'off',
// 禁止使用嵌套的三元表达式
'no-nested-ternary': 'off',
// 禁止直接 new 一个类而不赋值
'no-new': 'error',
// 禁止使用 new Function
'no-new-func': 'error',
// 禁止直接 new Object
'no-new-object': 'error',
// 禁止使用 new 来生成 Symbol
'no-new-symbol': 'error',
// 禁止使用 Math, JSON 或 Reflect 直接作为函数调用
'no-obj-calls': 'error',
// 禁止使用0开头的数字表示八进制数
'no-octal': 'off',
// 禁止使用八进制的转义符
'no-octal-escape': 'off',
// 禁止对函数的参数重新赋值
'no-param-reassign': 'error',
// 禁止使用 ++ 或 --
'no-plusplus': 'off',
// 禁止在Promise的回调函数中直接 return
'no-promise-executor-return': 'error',
// 禁止使用 __protp__
'no-proto': 'error',
// 禁止使用 hasOwnProperty, isPrototypeOf 或 propertyIsEnumerable
'no-prototype-builtins': 'off',
// 禁止重复定义变量
'no-redeclare': 'off',
// 禁止在正则表达式中出现连续的空格
'no-regex-spaces': 'error',
// 禁止导出指定的变量名
'no-regex-spaces': 'error',
// 禁止使用指定的全局变量
'no-restricted-globals': 'off',
// 禁止导入指定的模块
'no-restricted-imports': 'off',
// 禁止使用指定的对象属性
'no-restricted-properties': 'off',
// 禁止使用指定的语法
'no-restricted-syntax': 'off',
// 禁止在 return 语句里赋值
'no-return-assign': ['error', 'always'],
// 禁止在 return 语句里使用 await
'no-return-await': 'off',
// 禁止出现 location.href = 'javascript:void(0)'; @reason 有些场景下还是需要用到这个
'no-script-url': 'off',
// 禁止将自己赋值给自己
'no-self-assign': 'error',
// 禁止将自己与自己比较
'no-self-compare': 'error',
// 禁止使用逗号操作符
'no-sequences': 'error',
// 禁止 setter 有返回值
'no-setter-return': 'error',
// 禁止变量名与上层作用域内的已定义的变量重复
// @reason 很多时候函数的形参和传参是同名的
'no-shadow': 'off',
// 禁止使用保留字作为变量名
'no-shadow-restricted-names': 'error',
// 禁止在数组中出现连续的逗号
'no-sparse-arrays': 'error',
// 禁止在普通字符串中出现模版字符串里的变量形式
'no-template-curly-in-string': 'error',
// 禁止使用三元表达式
'no-ternary': 'off',
// 禁止在 super 被调用之前使用 this 或 super
'no-this-before-super': 'error',
// 禁止 throw 字面量,必须 throw 一个 Error 对象
'no-throw-literal': 'error',
// 禁止使用未定义的变量
'no-undef': 'error',
// 禁止将 undefined 赋值给变量
'no-undef-init': 'error',
// 禁止使用 undefined
'no-undefined': 'off',
// 禁止变量名出现下划线
'no-underscore-dangle': 'off',
// 循环内必须对循环条件中的变量有修改
'no-unmodified-loop-condition': 'error',
/**
* 必须使用 !a 替代 a ? false : true
* @reason 后者表达的更清晰
*/
'no-unneeded-ternary': 'off',
// 禁止在 return, throw, break 或 continue 之后还有代码
'no-unreachable': 'error',
// 禁止在第一轮循环时就一定会退出循环的情况出现
'no-unreachable-loop': 'error',
/**
* 禁止在 finally 中出现 return, throw, break 或 continue
* @reason finally 中的语句会在 try 之前执行
*/
'no-unsafe-finally': 'error',
// 禁止在 in 或 instanceof 操作符的左侧变量前使用感叹号
'no-unsafe-negation': 'error',
// 禁止无用的表达式
'no-unused-expressions': [
'error',
{
allowShortCircuit: true,
allowTernary: true,
allowTaggedTemplates: true
}
],
/**
* 禁止出现没用到的 label
* @reason 已经禁止使用 label 了
*/
'no-unused-labels': 'off',
// 已定义的变量必须使用
'no-unused-vars': [
'error',
{
vars: 'all',
args: 'none',
ignoreRestSiblings: false,
caughtErrors: 'none'
}
],
// 变量必须先定义后使用
'no-use-before-define': [
'error',
{
variables: false,
functions: false,
classes: false
}
],
// 禁止正则表达式中出现无用的回溯引用 @reason 某些回溯引用语法上没问题,但是会永远匹配到空字符串
'no-useless-backreference': 'error',
// 禁止出现没必要的 call 或 apply
'no-useless-call': 'error',
// 禁止在 catch 中仅仅只是把错误 throw 出去 @reason 这样的 catch 是没有意义的,等价于直接执行 try 里的代码
'no-useless-catch': 'error',
// 禁止出现没必要的计算键名
'no-useless-computed-key': 'error',
// 禁止出现没必要的字符串连接
'no-useless-concat': 'error',
// 禁止出现没必要的 constructor
'no-useless-constructor': 'error',
/**禁止出现没必要的转义
* @reason 转义可以使代码更易懂
*/
'no-useless-escape': 'off',
// 禁止解构赋值时出现同样名字的的重命名,比如 let { foo: foo } = bar;
'no-useless-rename': 'error',
// 禁止没必要的 return
'no-useless-return': 'off',
// 禁止使用 var
'no-var': 'error',
// 禁止使用 void
'no-void': 'error',
// 禁止注释中出现 TODO 和 FIXME
'no-warning-comments': 'off',
// 禁止使用 with @reason 编译阶段就会报错了
'no-with': 'off',
// 必须使用 a = {b} 而不是 a = {b: b} @reason 有时后者可以使代码结构更清晰
'object-shorthand': 'off',
// 禁止变量申明时用逗号一次申明多个
'one-var': ['error', 'never'],
// 必须使用 x = x + y 而不是 x += y
'operator-assignment': 'off',
// 限制语句之间的空行规则,比如变量定义完之后必须要空行
'padding-line-between-statements': 'off',
// 申明后不再被修改的变量必须使用 const 来申明
'prefer-const': 'off',
// 必须使用解构赋值
'prefer-destructuring': 'off',
// 使用 ES2016 的语法 ** 替代 Math.pow
'prefer-exponentiation-operator': 'off',
/**使用 ES2018 中的正则表达式命名组
* @reason 正则表达式已经较难理解了,没必要强制加上命名组
*/
'prefer-named-capture-group': 'off',
// 必须使用 0b11111011 而不是 parseInt()
'prefer-numeric-literals': 'off',
// 必须使用 ... 而不是 Object.assign,除非 Object.assign 的第一个参数是一个变量
'prefer-object-spread': 'error',
// Promise 的 reject 中必须传入 Error 对象,而不是字面量
'prefer-promise-reject-errors': 'error',
// 优先使用正则表达式字面量,而不是 RegExp 构造函数
'prefer-regex-literals': 'error',
// 必须使用 ...args 而不是 arguments
'prefer-rest-params': 'off',
// 必须使用 ... 而不是 apply,比如 foo(...args)
'prefer-spread': 'off',
// 必须使用模版字符串而不是字符串连接
'prefer-template': 'off',
// parseInt 必须传入第二个参数
radix: 'error',
/**
* 禁止将 await 或 yield 的结果做为运算符的后面项
* @reason 这样会导致不符合预期的结果
* https://github.com/eslint/eslint/issues/11899
* 在上面 issue 修复之前,关闭此规则
*/
'require-atomic-updates': 'off',
// async 函数中必须存在 await 语句
'require-await': 'off',
// 正则表达式中必须要加上 u 标志
'require-unicode-regexp': 'off',
// generator 函数内必须有 yield
'require-yield': 'error',
// 导入必须按规则排序
'sort-imports': 'off',
// 对象字面量的键名必须排好序
'sort-keys': 'off',
// 变量申明必须排好序
'sort-vars': 'off',
// 注释的斜线或 * 后必须有空格
'spaced-comment': [
'error',
'always',
{
block: {
exceptions: ['*'],
balanced: true
}
}
],
// 禁止使用 'strict';
strict: ['error', 'never'],
// 创建 Symbol 时必须传入参数
'symbol-description': 'error',
// 必须使用 isNaN(foo) 而不是 foo === NaN
'use-isnan': 'error',
// typeof 表达式比较的对象必须是 'undefined', 'object', 'boolean', 'number', 'string', 'function', 'symbol', 或 'bigint'
'valid-typeof': 'error',
// var 必须在作用域的最前面
'vars-on-top': 'off',
// 必须使用 if (foo === 5) 而不是 if (5 === foo)
yoda: [
'error',
'never',
{
onlyEquality: true
}
]
}
TypeScript规范
tsconfig.json
{
"compilerOptions": {
// 开启的特性
//
// 兼容 babel 模块导入的模式(不需要 * as)
"esModuleInterop": true,
// 支持引入 json 模块
"resolveJsonModule": true,
// React 项目需要配置此项
"jsx": "react",
// 禁止导入模块时大小写错误
"forceConsistentCasingInFileNames": true,
// 生成文件的配置
//
// 指定生成文件的 ECMAScript 版本
"target": "es2018",
// 指定生成哪个模块系统代码
"module": "commonjs",
// 决定如何处理模块
"moduleResolution": "node",
// 生成的文件的换行符
"newLine": "lf",
// 不生成输出
"noEmit": true,
// 严格模式,可选择性的开启,建议开启的越多越好
//
// 严格模式
"strict": true,
// 若有未使用的局部变量则抛错
"noUnusedLocals": true,
// 若有未使用的参数则抛错
"noUnusedParameters": true,
// stdout 输出
//
// 给错误和消息设置样式,使用颜色和上下文
"pretty": true
}
}
module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
rules: {
'react/sort-comp': 'off',
/**
* 重载的函数必须写在一起
* @reason 增加可读性
*/
'@typescript-eslint/adjacent-overload-signatures': 'error',
/**
* 限制数组类型必须使用 Array<T> 或 T[]
* @reason 允许灵活运用两者
*/
'@typescript-eslint/array-type': 'off',
/**
* 禁止对没有 then 方法的对象使用 await
*/
'@typescript-eslint/await-thenable': 'off',
/**
* 禁止使用 // @ts-ignore // @ts-nocheck // @ts-check
* @reason 这种注释本身就是对特殊代码的说明
*/
'@typescript-eslint/ban-ts-comment': 'off',
/**
* 禁止使用类似 tslint:disable-next-line 这样的注释
*/
'@typescript-eslint/ban-tslint-comment': 'off',
/**
* 禁止使用指定的类型
*/
'@typescript-eslint/ban-types': 'off',
/**
* 类的只读属性若是一个字面量,则必须使用只读属性而不是 getter
*/
'@typescript-eslint/class-literal-property-style': ['error', 'fields'],
/**
* 类型断言必须使用 as Type,禁止使用 <Type>,禁止对对象字面量进行类型断言(断言成 any 是允许的)
* @reason <Type> 容易被理解为 jsx
*/
'@typescript-eslint/consistent-type-assertions': [
'error',
{
assertionStyle: 'as',
objectLiteralTypeAssertions: 'never'
}
],
/**
* 优先使用 interface 而不是 type
* @reason interface 可以 implement, extend 和 merge
*/
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
/**
* 有默认值或可选的参数必须放到最后
*/
'default-param-last': 'off',
'@typescript-eslint/default-param-last': 'off',
/**
* 禁止使用 foo['bar'],必须写成 foo.bar
* @reason 当需要写一系列属性的时候,可以更统一
*/
'dot-notation': 'off',
'@typescript-eslint/dot-notation': 'off',
/**
* 函数返回值必须与声明的类型一致
* @reason 编译阶段检查就足够了
*/
'@typescript-eslint/explicit-function-return-type': 'off',
/**
* 必须设置类的成员的可访问性
* @reason 将不需要公开的成员设为私有的,可以增强代码的可理解性,对文档输出也很友好
*/
'@typescript-eslint/explicit-member-accessibility': 'error',
/**
* 导出的函数或类中的 public 方法必须定义输入输出参数的类型
*/
'@typescript-eslint/explicit-module-boundary-types': 'off',
/**
* 变量必须在定义的时候赋值
*/
'init-declarations': 'off',
'@typescript-eslint/init-declarations': 'off',
/**
* 类的成员之间是否需要空行
* @reason 有时为了紧凑需要挨在一起,有时为了可读性需要空一行
*/
'lines-between-class-members': 'off',
'@typescript-eslint/lines-between-class-members': 'off',
/**
* 指定类成员的排序规则
* @reason 优先级:
* 1. static > instance
* 2. field > constructor > method
* 3. public > protected > private
*/
'@typescript-eslint/member-ordering': [
'error',
{
default: [
'public-static-field',
'protected-static-field',
'private-static-field',
'static-field',
'public-static-method',
'protected-static-method',
'private-static-method',
'static-method',
'public-instance-field',
'protected-instance-field',
'private-instance-field',
'public-field',
'protected-field',
'private-field',
'instance-field',
'field',
'constructor',
'public-instance-method',
'protected-instance-method',
'private-instance-method',
'public-method',
'protected-method',
'private-method',
'instance-method',
'method'
]
}
],
/**
* 接口中的方法必须用属性的方式定义
* @reason 配置了 strictFunctionTypes 之后,用属性的方式定义方法可以获得更严格的检查
*/
'@typescript-eslint/method-signature-style': 'error',
/**
* 限制各种变量或类型的命名规则
*/
'@typescript-eslint/naming-convention': 'off',
/**
* 禁止使用 Array 构造函数
*/
'no-array-constructor': 'off',
'@typescript-eslint/no-array-constructor': 'off',
/**
* 禁止滥用 toString 方法
*/
'@typescript-eslint/no-base-to-string': 'off',
/**
* 禁止使用容易混淆的非空断言
*/
'@typescript-eslint/no-confusing-non-null-assertion': 'off',
/**
* 禁止重复定义类的成员
* @reason 编译阶段就会报错了
*/
'no-dupe-class-members': 'off',
'@typescript-eslint/no-dupe-class-members': 'off',
/**
* 禁止 delete 时传入的 key 是动态的
*/
'@typescript-eslint/no-dynamic-delete': 'off',
/**
* 不允许有空函数
* @reason 有时需要将一个空函数设置为某个项的默认值
*/
'no-empty-function': 'off',
'@typescript-eslint/no-empty-function': 'off',
/**
* 禁止定义空的接口
*/
'@typescript-eslint/no-empty-interface': 'error',
/**
* 禁止使用 any
*/
'@typescript-eslint/no-explicit-any': 'off',
/**
* 禁止多余的 non-null 断言
*/
'@typescript-eslint/no-extra-non-null-assertion': 'off',
/**
* 禁止定义没必要的类,比如只有静态方法的类
*/
'@typescript-eslint/no-extraneous-class': 'off',
/**
* 禁止调用 Promise 时没有处理异常情况
*/
'@typescript-eslint/no-floating-promises': 'off',
/**
* 禁止对 array 使用 for in 循环
*/
'@typescript-eslint/no-for-in-array': 'off',
/**
* 禁止使用 eval
*/
'@typescript-eslint/no-implied-eval': 'off',
/**
* 禁止给一个初始化时直接赋值为 number, string 的变量显式的声明类型
* @reason 可以简化代码
*/
'@typescript-eslint/no-inferrable-types': 'error',
/**
* 禁止在类之外的地方使用 this
* @reason 只允许在 class 中使用 this
*/
'no-invalid-this': 'off',
'@typescript-eslint/no-invalid-this': 'error',
/**
* 禁止使用无意义的 void 类型
* @reason void 只能用在函数的返回值中
*/
'@typescript-eslint/no-invalid-void-type': 'error',
/**
* 禁止使用超出 js 精度范围的数字
*/
'no-loss-of-precision': 'off',
'@typescript-eslint/no-loss-of-precision': 'error',
/**
* 禁止使用 magic numbers
*/
'no-magic-numbers': 'off',
'@typescript-eslint/no-magic-numbers': 'off',
/**
* 禁止在接口中定义 constructor,或在类中定义 new
*/
'@typescript-eslint/no-misused-new': 'off',
/**
* 避免错误的使用 Promise
*/
'@typescript-eslint/no-misused-promises': 'off',
/**
* 禁止使用 namespace 来定义命名空间
* @reason 使用 es6 引入模块,才是更标准的方式。
* 但是允许使用 declare namespace ... {} 来定义外部命名空间
*/
'@typescript-eslint/no-namespace': [
'error',
{
allowDeclarations: true,
allowDefinitionFiles: true
}
],
/**
* 禁止在 optional chaining 之后使用 non-null 断言(感叹号)
* @reason optional chaining 后面的属性一定是非空的
*/
'@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
/**
* 禁止使用 non-null 断言(感叹号)
* @reason 使用 non-null 断言时就已经清楚了风险
*/
'@typescript-eslint/no-non-null-assertion': 'off',
/**
* 禁止给类的构造函数的参数添加修饰符
* @reason 强制所有属性都定义到类里面,比较统一
*/
'@typescript-eslint/no-parameter-properties': 'error',
/**
* 禁止使用 require
* @reason 统一使用 import 来引入模块,特殊情况使用单行注释允许 require 引入
*/
'@typescript-eslint/no-require-imports': 'error',
/**
* 禁止将 this 赋值给其他变量,除非是解构赋值
*/
'@typescript-eslint/no-this-alias': [
'error',
{
allowDestructuring: true
}
],
/**
* 禁止 throw 字面量,必须 throw 一个 Error 对象
*/
'@typescript-eslint/no-throw-literal': 'off',
/**
* 禁止使用类型别名
*/
'@typescript-eslint/no-type-alias': 'off',
/**
* 测试表达式中的布尔类型禁止与 true 或 false 直接比较
*/
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'off',
/**
* 条件表达式禁止是永远为真(或永远为假)的
*/
'@typescript-eslint/no-unnecessary-condition': 'off',
/**
* 在命名空间中,可以直接使用内部变量,不需要添加命名空间前缀
*/
'@typescript-eslint/no-unnecessary-qualifier': 'off',
/**
* 禁止范型的类型有默认值时,将范型设置为该默认值
*/
'@typescript-eslint/no-unnecessary-type-arguments': 'off',
/**
* 禁止无用的类型断言
*/
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
/**
* 禁止将变量或属性的类型设置为 any
*/
'@typescript-eslint/no-unsafe-assignment': 'off',
/**
* 禁止调用 any 类型的变量上的方法
*/
'@typescript-eslint/no-unsafe-call': 'off',
/**
* 禁止获取 any 类型的变量中的属性
*/
'@typescript-eslint/no-unsafe-member-access': 'off',
/**
* 禁止函数的返回值的类型是 any
*/
'@typescript-eslint/no-unsafe-return': 'off',
/**
* 禁止无用的表达式
*/
'no-unused-expressions': 'off',
'@typescript-eslint/no-unused-expressions': [
'error',
{
allowShortCircuit: true,
allowTernary: true,
allowTaggedTemplates: true
}
],
/**
* 已定义的变量必须使用
* @reason 编译阶段检查就足够了
*/
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'off',
/**
* 禁止已定义的变量未使用
*/
'@typescript-eslint/no-unused-vars-experimental': 'off',
/**
* 禁止在定义变量之前就使用它
* @reason 编译阶段检查就足够了
*/
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': 'off',
/**
* 禁止出现没必要的 constructor
*/
'no-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 'error',
/**
* 禁止使用 require 来引入模块
* @reason no-require-imports 规则已经约束了 require
*/
'@typescript-eslint/no-var-requires': 'off',
/**
* 使用 as const 替代 as 'bar'
* @reason as const 是新语法,不是很常见
*/
'@typescript-eslint/prefer-as-const': 'off',
/**
* 使用 for 循环遍历数组时,如果索引仅用于获取成员,则必须使用 for of 循环替代 for 循环
* @reason for of 循环更加易读
*/
'@typescript-eslint/prefer-for-of': 'error',
/**
* 使用函数类型别名替代包含函数调用声明的接口
*/
'@typescript-eslint/prefer-function-type': 'error',
/**
* 使用 includes 而不是 indexOf
*/
'@typescript-eslint/prefer-includes': 'off',
/**
* 枚举类型的值必须是字面量,禁止是计算值
* @reason 编译阶段检查就足够了
*/
'@typescript-eslint/prefer-literal-enum-member': 'off',
/**
* 禁止使用 module 来定义命名空间
* @reason module 已成为 js 的关键字
*/
'@typescript-eslint/prefer-namespace-keyword': 'error',
/**
* 使用 ?? 替代 ||
*/
'@typescript-eslint/prefer-nullish-coalescing': 'off',
/**
* 使用 optional chaining 替代 &&
*/
'@typescript-eslint/prefer-optional-chain': 'error',
/**
* 私有变量如果没有在构造函数外被赋值,则必须设为 readonly
*/
'@typescript-eslint/prefer-readonly': 'off',
/**
* 函数的参数必须设置为 readonly
*/
'@typescript-eslint/prefer-readonly-parameter-types': 'off',
/**
* 使用 reduce 方法时,必须传入范型,而不是对第二个参数使用 as
*/
'@typescript-eslint/prefer-reduce-type-parameter': 'off',
/**
* 使用 RegExp#exec 而不是 String#match
*/
'@typescript-eslint/prefer-regexp-exec': 'off',
/**
* 使用 String#startsWith 而不是其他方式
*/
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
/**
* 当需要忽略下一行的 ts 错误时,必须使用 @ts-expect-error 而不是 @ts-ignore
* @reason 使用 @ts-expect-error 可以避免对不会报错的代码设置了 @ts-ignore
*/
'@typescript-eslint/prefer-ts-expect-error': 'off',
/**
* async 函数的返回值必须是 Promise
*/
'@typescript-eslint/promise-function-async': 'off',
/**
* 使用 sort 时必须传入比较函数
*/
'@typescript-eslint/require-array-sort-compare': 'off',
/**
* async 函数中必须存在 await 语句
*/
'require-await': 'off',
'@typescript-eslint/require-await': 'off',
/**
* 使用加号时,两者必须同为数字或同为字符串
*/
'@typescript-eslint/restrict-plus-operands': 'off',
/**
* 模版字符串中的变量类型必须是字符串
*/
'@typescript-eslint/restrict-template-expressions': 'off',
/**
* 禁止在 return 语句里使用 await
*/
'no-return-await': 'off',
'@typescript-eslint/return-await': 'off',
/**
* 条件判断必须传入布尔值
*/
'@typescript-eslint/strict-boolean-expressions': 'off',
/**
* 使用联合类型作为 switch 的对象时,必须包含每一个类型的 case
*/
'@typescript-eslint/switch-exhaustiveness-check': 'off',
/**
* 禁止使用三斜杠导入文件
* @reason 三斜杠是已废弃的语法,但在类型声明文件中还是可以使用的
*/
'@typescript-eslint/triple-slash-reference': [
'error',
{
path: 'never',
types: 'always',
lib: 'always'
}
],
/**
* interface 和 type 定义时必须声明成员的类型
*/
'@typescript-eslint/typedef': [
'error',
{
arrayDestructuring: false,
arrowParameter: false,
memberVariableDeclaration: false,
objectDestructuring: false,
parameter: false,
propertyDeclaration: true,
variableDeclaration: false
}
],
/**
* 方法调用时需要绑定到正确的 this 上
*/
'@typescript-eslint/unbound-method': 'off',
/**
* 函数重载时,若能通过联合类型将两个函数的类型声明合为一个,则使用联合类型而不是两个函数声明
*/
'@typescript-eslint/unified-signatures': 'error'
}
};
Vue单文件规范
module.exports = {
parser: 'vue-eslint-parser',
parserOptions: {
// 设置 js 的解析器为 babel-eslint
// https://github.com/mysticatea/vue-eslint-parser#-options
parser: 'babel-eslint',
ecmaVersion: 2019,
// ECMAScript modules 模式
sourceType: 'module',
ecmaFeatures: {
// 不允许 return 语句出现在 global 环境下
globalReturn: false,
// 开启全局 script 模式
impliedStrict: true,
jsx: true
},
// 即使没有 babelrc 配置文件,也使用 babel-eslint 来解析
requireConfigFile: false,
// 仅允许 import export 语句出现在模块的顶层
allowImportExportEverywhere: false
},
plugins: ['vue'],
rules: {
/**
* 限制自定义组件的属性风格
*/
'vue/attribute-hyphenation': 'off',
/**
* 标签属性必须按规则排序
*/
'vue/attributes-order': 'error',
/**
* 变量名必须是 camelcase 风格的
* @reason 很多 api 或文件名都不是 camelcase 风格的
*/
'vue/camelcase': 'off',
/**
* 支持在模版中使用 eslint-disable-next-line 等注释
*/
'vue/comment-directive': 'error',
/**
* 组件的 name 属性必须符合 PascalCase
* @reason 这是官方建议的规范
*/
'vue/component-definition-name-casing': ['error', 'PascalCase'],
/**
* 限制组件名的风格
*/
'vue/component-name-in-template-casing': 'off',
/**
* 组件中必须按照 <script>, <template>, <style> 排序
* @reason 这是官方建议的顺序
*/
'vue/component-tags-order': [
'error',
{
order: ['script', 'template', 'style']
}
],
/**
* 必须使用 === 或 !==,禁止使用 == 或 !=
*/
'vue/eqeqeq': ['error', 'always'],
/**
* 修复 no-unused-vars 不检查 jsx 的问题
*/
'vue/jsx-uses-vars': 'error',
/**
* 组件名称必须和文件名一致
*/
'vue/match-component-file-name': 'off',
/**
* 限制组件的 name 属性的值的风格
*/
'vue/name-property-casing': 'off',
/**
* 计算属性禁止包含异步方法
*/
'vue/no-async-in-computed-properties': 'error',
/**
* 禁止给布尔值 props 添加默认值
* @reason 类型相关的约束交给 TypeScript
*/
'vue/no-boolean-default': 'off',
/**
* 禁用已废弃的 scope 属性
*/
'vue/no-deprecated-scope-attribute': 'error',
/**
* 使用 v-slot 替代已废弃的 slot
*/
'vue/no-deprecated-slot-attribute': 'error',
/**
* 禁用已废弃的 slot-scope
*/
'vue/no-deprecated-slot-scope-attribute': 'error',
/**
* 禁止重复的键名
*/
'vue/no-dupe-keys': 'error',
/**
* 禁止出现重复的属性
*/
'vue/no-duplicate-attributes': [
'error',
{
allowCoexistClass: false,
allowCoexistStyle: false
}
],
/**
* 禁止解构赋值中出现空 {} 或 []
*/
'vue/no-empty-pattern': 'error',
/**
* 禁止使用特殊空白符(比如全角空格),除非是出现在字符串、正则表达式、模版字符串中或 HTML 内容中
*/
'vue/no-irregular-whitespace': [
'error',
{
skipStrings: true,
skipComments: false,
skipRegExps: true,
skipTemplates: true,
skipHTMLTextContents: true
}
],
/**
* 禁止出现语法错误
*/
'vue/no-parsing-error': 'error',
/**
* 组件的 name 属性静止使用保留字
*/
'vue/no-reserved-component-names': 'error',
/**
* 禁止覆盖保留字
*/
'vue/no-reserved-keys': 'error',
/**
* 禁止使用指定的语法
*/
'vue/no-restricted-syntax': 'off',
/**
* 组件的 data 属性的值必须是一个函数
*/
'vue/no-shared-component-data': 'off',
/**
* 禁止在计算属性中对属性修改
*/
'vue/no-side-effects-in-computed-properties': 'off',
/**
* 禁止使用 style 属性
*/
'vue/no-static-inline-styles': 'off',
/**
* 禁止 <template> 使用 key 属性
*/
'vue/no-template-key': 'off',
/**
* 模版中的变量名禁止与前一个作用域重名
*/
'vue/no-template-shadow': 'off',
/**
* 禁止在 <textarea> 中出现模版语法
*/
'vue/no-textarea-mustache': 'error',
/**
* 当你的 vue 版本较老时,禁用还未支持的语法
*/
'vue/no-unsupported-features': 'off',
/**
* 禁止定义在 components 中的组件未使用
*/
'vue/no-unused-components': 'error',
/**
* 模版中已定义的变量必须使用
*/
'vue/no-unused-vars': 'error',
/**
* 禁止在同一个元素上使用 v-if 和 v-for 指令
*/
'vue/no-use-v-if-with-v-for': 'error',
/**
* 禁止使用 v-html
*/
'vue/no-v-html': 'off',
/**
* 组件的属性必须为一定的顺序
*/
'vue/order-in-components': 'error',
/**
* <template> <script> <style> 之间必须由空行
* @reason 代码格式问题,最好由 Prettier 解决
*/
'vue/padding-line-between-blocks': 'off',
/**
* props 必须用驼峰式
*/
'vue/prop-name-casing': 'off',
/**
* <component> 必须有绑定的组件
*/
'vue/require-component-is': 'error',
/**
* props 如果不是 required 的字段,必须有默认值
* @reason 类型相关的约束交给 TypeScript
*/
'vue/require-default-prop': 'off',
/**
* 必须直接使用 export default 导出组件
*/
'vue/require-direct-export': 'off',
/**
* 组件必须包含 name 属性
*/
'vue/require-name-property': 'off',
/**
* props 的取值必须是基本类型的构造函数,而不是字符串
* @reason 类型相关的约束交给 TypeScript
*/
'vue/require-prop-type-constructor': 'off',
/**
* prop 必须有类型限制
* @reason 类型相关的约束交给 TypeScript
*/
'vue/require-prop-types': 'off',
/**
* render 函数必须有返回值
*/
'vue/require-render-return': 'error',
/**
* v-for 指令的元素必须有 v-bind:key
*/
'vue/require-v-for-key': 'error',
/**
* prop 的默认值必须匹配它的类型
* @reason 类型相关的约束交给 TypeScript
*/
'vue/require-valid-default-prop': 'off',
/**
* 计算属性必须有返回值
*/
'vue/return-in-computed-property': 'error',
/**
* props 的键名必须排好序
*/
'vue/sort-keys': 'off',
/**
* class 的值必须按字母排序
*/
'vue/static-class-names-order': 'off',
/**
* 禁止在模版中用 this
*/
'vue/this-in-template': 'error',
/**
* 当一个节点上出现两个 v-on:click 时,其中一个必须为 exact
*/
'vue/use-v-on-exact': 'error',
/**
* 使用缩写的 : 而不是 v-bind:
*/
'vue/v-bind-style': 'error',
/**
* 禁止在 v-on 的值中调用函数
*/
'vue/v-on-function-call': 'error',
/**
* 使用缩写的 @click 而不是 v-on:click
*/
'vue/v-on-style': 'error',
/**
* 使用缩写的 #one 而不是 v-slot:one
*/
'vue/v-slot-style': 'off',
/**
* template 的根节点必须合法
*/
'vue/valid-template-root': 'error',
/**
* v-bind 指令必须合法
*/
'vue/valid-v-bind': 'error',
/**
* v-bind:foo.sync 指令必须合法
*/
'vue/valid-v-bind-sync': 'error',
/**
* v-cloak 指令必须合法
*/
'vue/valid-v-cloak': 'error',
/**
* v-else 指令必须合法
*/
'vue/valid-v-else': 'error',
/**
* v-else-if 指令必须合法
*/
'vue/valid-v-else-if': 'error',
/**
* v-for 指令必须合法
*/
'vue/valid-v-for': 'error',
/**
* v-html 指令必须合法
*/
'vue/valid-v-html': 'error',
/**
* v-if 指令必须合法
*/
'vue/valid-v-if': 'error',
/**
* v-model 指令必须合法
*/
'vue/valid-v-model': 'error',
/**
* v-on 指令必须合法
*/
'vue/valid-v-on': 'error',
/**
* v-once 指令必须合法
*/
'vue/valid-v-once': 'error',
/**
* v-pre 指令必须合法
*/
'vue/valid-v-pre': 'error',
/**
* v-show 指令必须合法
*/
'vue/valid-v-show': 'error',
/**
* v-slot 指令必须合法
*/
'vue/valid-v-slot': 'error',
/**
* v-text 指令必须合法
*/
'vue/valid-v-text': 'error'
}
};