# ESLint、Prettier、VueUse 从入门到应用实践

TIP

本章我们一起来学习 ESLint 代码检查工具、Prettier 代码格式化工具、VueUse(基于 Vue 组合式 API 的实用函数集合)工具。

# 一、ESLint

TIP

当我们在进行团队协作开发项目时,每个人的代码习惯和理解的差异会导致团队中出现各种各样规范的代码。如:有的人认为语句后应加冒号,有的人认为不应该加;有的人习惯用单引号来包裹字符串,有的人习惯用双引号包裹字符串等之类的各种问题。

这种差异性会造成团队协作效率低下,也会影响项目的健壮性和可维护性。所以我们需要对代码风格进行规范,这种规范有以下好处:

  • 代码风格保持统一
  • 并且可以在代码运行之前检测出错误和 bug,提高协作开发效率

ESLint 工具就可以帮助我们解决代码规范问题。

# 1、什么是 ESLint

TIP

ESLint 是一个 JavaScript 的 Lint(静态代码分析)工具,其目的使代码风格更加一致并避免错误。他可以帮助我们在运行代码前就发现语法错误和潜在的 bug,非常适合用于制定团队代码规范。

ESLint 官网:http://eslint.cn/

本章节我们将重点学习 ESLint 的以下 2 方面内容

  • ESLint 的基本使用
  • ESLint 配置文件

# 2、ESLint 的基本使用

TIP

ESLint 是用来对项目中的代码进行统一规范,所以 ESLint 必须结合项目来使用。

首先我们需要创建一个项目目录,然后执行以下命令,初始化package.json文件

npm init -y   #初始化package.json文件

接下来就可以按下面步骤在项目中安装并使用 ESLint 工具。

# 3、安装并配置 ESLint

TIP

你可以使用该命令安装并配置 ESLint

npm init @eslint/config

以上命令执行后,在控制台会提出一系列的问题让我们来选择,根据自身项目情况选择即可。

问题一:How would you like to use ESLint? (你希望如何使用 ESLint)

image-20231010143447400

  • 问题二:what type of modules does your project use (你的项目使用什么类型的模块)

image-20231010143929084

  • 问题三:Which framework does your project use (您的项目使用哪个框架)

image-20231010144234384

  • 问题四:Does your project use TypeScript? (你的项目使用 TypeScript 吗?)

image-20231010144416021

  • 问题五:where does your code run (你的代码在哪里运行)

image-20231010144811464

问题六:What format do you want your config file to be in (您希望配置文件的格式是什么)

image-20231010145121449

image-20231010145353037

问题七:Which package manager do you want to use? (您要使用哪个程序包管理器?)

image-20231010145516879

最后安装成功

image-20231010145646444

安装成功后,在当前根目录下会生成.eslintrc.js文件,该文件为 ESLint 的配置文件。默认生成后的内容如下:

module.exports = {
  env: {
    browser: true,
    commonjs: true,
    es2021: true,
  },
  extends: "eslint:recommended",
  overrides: [
    {
      env: {
        node: true,
      },
      files: [".eslintrc.{js,cjs}"],
      parserOptions: {
        sourceType: "script",
      },
    },
  ],
  parserOptions: {
    ecmaVersion: "latest",
  },
  rules: {},
};

以上配置文件中各个配置项的具体含义和作用,我们放在后面 ESLint 配置文件版块再讲。

# 4、使用 ESLint 工具

TIP

我们可以在当前项目下新建src/test.js文件,然后书写如下代码

function sum(a, b) {
  console.log(a + b);
  return a + b;
}

使用 ESLint 命令行检查src/test.js文件中代码

npx eslint ./src/test.js  # 检查src/test.js文件中代码是否符合规范
# 或
npx eslint ./src  # 检查 ./src 目录下的所有JS文件是否符合规范

会发现,在控制台抛出了如下一个错误

image-20231010151004758

如果我们把配置文件中的"extends": "eslint:recommended", 换成 "extends": "eslint:all"

再执行 npx eslint ./src时,会在控制台抛出如下错误

image-20231010151913558

原因在于

  • eslint:recommended 内置规范包, 只有 60 条左右的代码规范
  • eslint:all 内置规范包,包含所有(280 条)的代码规范

# 5、修复问题 --fix

TIP

执行以下命令可以修复存在的部分规范问题,但不是所有的问题都可以用此项来修复

npx eslint --fix ./src

命令执行后,部分问题会被自动修复,但仍有以下问题是没有办法修复的,需要人为去修复。

image-20231010152449235

最终人为将代码修改成如下内容,然后执行npx eslint ./src命令后,将没有任何错误信息

"use strict";
const aa = 1,
  bb = 2,
  sum = function sum(a1, b1) {
    return a1 + b1;
  };
sum(aa, bb);

# 6、VSCode 中安装 ESLint 插件

TIP

通过前面的代码演示我们知道,只有当我们执行npx eslint ...命令时,才会调用 eslint 来帮助我们检查代码。

如果我们想在编写代码的时候,一旦出现不符合要求的代码,就给你们提示,就需要借助 VSCode 的 ESLint 插件。

按以下截图安装 VSCode 的 ESLint 插件

image-20231010180100855

注:

VSCode 的 ESLint 插件对代码的检查规则是:

  • 如果当前项目目录下有.eslintrc文件,就会按该文件中配置的规则来检测代码,
  • 如果没有,就会按插件本身的默认规则来。

# 二、ESLint 配置文件

TIP

深入浅出 ESLint 配置文件

# 1、配置文件格式

TIP

配置文件有.js .yml .json 三种格式。

# 2、env 节点

TIP

  • env 用于启用特定环境的全局变量。

  • 由于 ESLint 的各种规范中,一般都不允许使用未在页面内声明的成员(变量),而在开发中经常会用到一些运行环境自带的全局变量,如:

    • 浏览器中的 windowdocument
    • nodejs 中的 __dirname
    • es2021 中的 WeakRef 等

如果我们没有启用任何特定环境全局变量,那我们在代码中使用了 window,document 时,ESLint 就会认为这两个变量没有定义,会抛出未定义的错误。

所以我们需要告诉 ESLint,当前代码运行在哪个环中,这些环境下的全局变量检查时就不会报错。

代码测式一

"env": {
    "browser": true,  //  启用浏览器环境下的全局变量
},

如果 env 中指定了以上配置,以下代码在 ESLint 检测时,不会抛出错误

window.a = 1;

代码测试二

"env": {
   //  "browser": true,
},

如果 env 中没有启用特定环境的全局变量,则以下代码在 ESLint 检测时,会抛出如下错误

image-20231010185919494

查阅 ESLint 官网,了解更多可用的环境 (opens new window)

# 3、extends 节点

TIP

extends 用于配置 ESLint 使用那种规则包来检查代码。

规则包分为以下 2 类:

①、ESLint 内置规范包:

  • eslint-all 要使用全部 280 多个规则
  • eslint-recommended 只需要满足部分核心规则
  "extends": "eslint:recommended", // 使用内置的推荐规则包

eslint-all包与eslint-recommended包的所有规则,查阅 ESLint规则参考 (opens new window)

②、第三方规范包

extends: "standard",    // 使用 eslint-config-standard 规则包

使用这个规则包之前,要执行以下命令安装相关包

npm install --save-dev eslint-config-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-n

standard 包指定了哪些规则,可以在node_modules/eslint-config-standard/index.js中可以查看到,具体如下:

{
  "parserOptions": {
    "ecmaVersion": 2022,
    "ecmaFeatures": {
      "jsx": true
    },
    "sourceType": "module"
  },

  "env": {
    "es2021": true,
    "node": true
  },

  "plugins": [
    "import",
    "n",
    "promise"
  ],

  "globals": {
    "document": "readonly",
    "navigator": "readonly",
    "window": "readonly"
  },

  "rules": {
    "no-var": "warn",
    "object-shorthand": ["warn", "properties"],

    "accessor-pairs": ["error", { "setWithoutGet": true, "enforceForClassMembers": true }],
    "array-bracket-spacing": ["error", "never"],
    "array-callback-return": ["error", {
      "allowImplicit": false,
      "checkForEach": false
    }],
    "arrow-spacing": ["error", { "before": true, "after": true }],
    "block-spacing": ["error", "always"],
    "brace-style": ["error", "1tbs", { "allowSingleLine": true }],
    "camelcase": ["error", {
      "allow": ["^UNSAFE_"],
      "properties": "never",
      "ignoreGlobals": true
    }],
    "comma-dangle": ["error", {
      "arrays": "never",
      "objects": "never",
      "imports": "never",
      "exports": "never",
      "functions": "never"
    }],
    "comma-spacing": ["error", { "before": false, "after": true }],
    "comma-style": ["error", "last"],
    "computed-property-spacing": ["error", "never", { "enforceForClassMembers": true }],
    "constructor-super": "error",
    "curly": ["error", "multi-line"],
    "default-case-last": "error",
    "dot-location": ["error", "property"],
    "dot-notation": ["error", { "allowKeywords": true }],
    "eol-last": "error",
    "eqeqeq": ["error", "always", { "null": "ignore" }],
    "func-call-spacing": ["error", "never"],
    "generator-star-spacing": ["error", { "before": true, "after": true }],
    "indent": ["error", 2, {
      "SwitchCase": 1,
      "VariableDeclarator": 1,
      "outerIIFEBody": 1,
      "MemberExpression": 1,
      "FunctionDeclaration": { "parameters": 1, "body": 1 },
      "FunctionExpression": { "parameters": 1, "body": 1 },
      "CallExpression": { "arguments": 1 },
      "ArrayExpression": 1,
      "ObjectExpression": 1,
      "ImportDeclaration": 1,
      "flatTernaryExpressions": false,
      "ignoreComments": false,
      "ignoredNodes": ["TemplateLiteral *", "JSXElement", "JSXElement > *", "JSXAttribute", "JSXIdentifier", "JSXNamespacedName", "JSXMemberExpression", "JSXSpreadAttribute", "JSXExpressionContainer", "JSXOpeningElement", "JSXClosingElement", "JSXFragment", "JSXOpeningFragment", "JSXClosingFragment", "JSXText", "JSXEmptyExpression", "JSXSpreadChild"],
      "offsetTernaryExpressions": true
    }],
    "key-spacing": ["error", { "beforeColon": false, "afterColon": true }],
    "keyword-spacing": ["error", { "before": true, "after": true }],
    "lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }],
    "multiline-ternary": ["error", "always-multiline"],
    "new-cap": ["error", { "newIsCap": true, "capIsNew": false, "properties": true }],
    "new-parens": "error",
    "no-array-constructor": "error",
    "no-async-promise-executor": "error",
    "no-caller": "error",
    "no-case-declarations": "error",
    "no-class-assign": "error",
    "no-compare-neg-zero": "error",
    "no-cond-assign": "error",
    "no-const-assign": "error",
    "no-constant-condition": ["error", { "checkLoops": false }],
    "no-control-regex": "error",
    "no-debugger": "error",
    "no-delete-var": "error",
    "no-dupe-args": "error",
    "no-dupe-class-members": "error",
    "no-dupe-keys": "error",
    "no-duplicate-case": "error",
    "no-useless-backreference": "error",
    "no-empty": ["error", { "allowEmptyCatch": true }],
    "no-empty-character-class": "error",
    "no-empty-pattern": "error",
    "no-eval": "error",
    "no-ex-assign": "error",
    "no-extend-native": "error",
    "no-extra-bind": "error",
    "no-extra-boolean-cast": "error",
    "no-extra-parens": ["error", "functions"],
    "no-fallthrough": "error",
    "no-floating-decimal": "error",
    "no-func-assign": "error",
    "no-global-assign": "error",
    "no-implied-eval": "error",
    "no-import-assign": "error",
    "no-invalid-regexp": "error",
    "no-irregular-whitespace": "error",
    "no-iterator": "error",
    "no-labels": ["error", { "allowLoop": false, "allowSwitch": false }],
    "no-lone-blocks": "error",
    "no-loss-of-precision": "error",
    "no-misleading-character-class": "error",
    "no-prototype-builtins": "error",
    "no-useless-catch": "error",
    "no-mixed-operators": ["error", {
      "groups": [
        ["==", "!=", "===", "!==", ">", ">=", "<", "<="],
        ["&&", "||"],
        ["in", "instanceof"]
      ],
      "allowSamePrecedence": true
    }],
    "no-mixed-spaces-and-tabs": "error",
    "no-multi-spaces": "error",
    "no-multi-str": "error",
    "no-multiple-empty-lines": ["error", { "max": 1, "maxBOF": 0, "maxEOF": 0 }],
    "no-new": "error",
    "no-new-func": "error",
    "no-new-object": "error",
    "no-new-symbol": "error",
    "no-new-wrappers": "error",
    "no-obj-calls": "error",
    "no-octal": "error",
    "no-octal-escape": "error",
    "no-proto": "error",
    "no-redeclare": ["error", { "builtinGlobals": false }],
    "no-regex-spaces": "error",
    "no-return-assign": ["error", "except-parens"],
    "no-self-assign": ["error", { "props": true }],
    "no-self-compare": "error",
    "no-sequences": "error",
    "no-shadow-restricted-names": "error",
    "no-sparse-arrays": "error",
    "no-tabs": "error",
    "no-template-curly-in-string": "error",
    "no-this-before-super": "error",
    "no-throw-literal": "error",
    "no-trailing-spaces": "error",
    "no-undef": "error",
    "no-undef-init": "error",
    "no-unexpected-multiline": "error",
    "no-unmodified-loop-condition": "error",
    "no-unneeded-ternary": ["error", { "defaultAssignment": false }],
    "no-unreachable": "error",
    "no-unreachable-loop": "error",
    "no-unsafe-finally": "error",
    "no-unsafe-negation": "error",
    "no-unused-expressions": ["error", {
      "allowShortCircuit": true,
      "allowTernary": true,
      "allowTaggedTemplates": true
    }],
    "no-unused-vars": ["error", {
      "args": "none",
      "caughtErrors": "none",
      "ignoreRestSiblings": true,
      "vars": "all"
    }],
    "no-use-before-define": ["error", { "functions": false, "classes": false, "variables": false }],
    "no-useless-call": "error",
    "no-useless-computed-key": "error",
    "no-useless-constructor": "error",
    "no-useless-escape": "error",
    "no-useless-rename": "error",
    "no-useless-return": "error",
    "no-void": "error",
    "no-whitespace-before-property": "error",
    "no-with": "error",
    "object-curly-newline": ["error", { "multiline": true, "consistent": true }],
    "object-curly-spacing": ["error", "always"],
    "object-property-newline": ["error", { "allowMultiplePropertiesPerLine": true }],
    "one-var": ["error", { "initialized": "never" }],
    "operator-linebreak": ["error", "after", { "overrides": { "?": "before", ":": "before", "|>": "before" } }],
    "padded-blocks": ["error", { "blocks": "never", "switches": "never", "classes": "never" }],
    "prefer-const": ["error", {"destructuring": "all"}],
    "prefer-promise-reject-errors": "error",
    "prefer-regex-literals": ["error", { "disallowRedundantWrapping": true }],
    "quote-props": ["error", "as-needed"],
    "quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": false }],
    "rest-spread-spacing": ["error", "never"],
    "semi": ["error", "never"],
    "semi-spacing": ["error", { "before": false, "after": true }],
    "space-before-blocks": ["error", "always"],
    "space-before-function-paren": ["error", "always"],
    "space-in-parens": ["error", "never"],
    "space-infix-ops": "error",
    "space-unary-ops": ["error", { "words": true, "nonwords": false }],
    "spaced-comment": ["error", "always", {
      "line": { "markers": ["*package", "!", "/", ",", "="] },
      "block": { "balanced": true, "markers": ["*package", "!", ",", ":", "::", "flow-include"], "exceptions": ["*"] }
    }],
    "symbol-description": "error",
    "template-curly-spacing": ["error", "never"],
    "template-tag-spacing": ["error", "never"],
    "unicode-bom": ["error", "never"],
    "use-isnan": ["error", {
      "enforceForSwitchCase": true,
      "enforceForIndexOf": true
    }],
    "valid-typeof": ["error", { "requireStringLiterals": true }],
    "wrap-iife": ["error", "any", { "functionPrototypeMethods": true }],
    "yield-star-spacing": ["error", "both"],
    "yoda": ["error", "never"],

    "import/export": "error",
    "import/first": "error",
    "import/no-absolute-path": ["error", { "esmodule": true, "commonjs": true, "amd": false }],
    "import/no-duplicates": "error",
    "import/no-named-default": "error",
    "import/no-webpack-loader-syntax": "error",

    "n/handle-callback-err": ["error", "^(err|error)$" ],
    "n/no-callback-literal": "error",
    "n/no-deprecated-api": "error",
    "n/no-exports-assign": "error",
    "n/no-new-require": "error",
    "n/no-path-concat": "error",
    "n/process-exit-as-throw": "error",

    "promise/param-names": "error"
  }
}

standard 规则中使用单引号、首行缩进 2 个空格,对象属性不用加引号,这样.eslintrc.js文件格式不符合要求,需要对配置文件单独配置这些规则。如下:

"overrides": [
        {
            "files": [
                ".eslintrc.{js,cjs}"
            ],
            "parserOptions": {
                "sourceType": "script"
            },
            "rules": {
                "quotes": [2, "double"],  // 双引号
                "indent": ["error", 4],  // 首行缩进4个字符
                "quote-props": ["error", "always"]  // 对象属性名用双号号
            }
        }
    ],

注意:

  • 在使用第三方规范包时,一定要记得先下载对应的包,包的使用教程在 npm 上查询。
  • 所有以eslint-config-前缀的规则包,可以省略 eslint-config-前缀

# 4、overrides 节点

TIP

有时同一目录下的文件的配置不同。

因此,你可以在 overrides 键下提供配置,这些配置只应用于特定的文件。

module.exports = {
  env: {
    browser: true,
    commonjs: true,
    es2021: true,
  },
  extends: "standard",
  overrides: [
    // 针对.eslintrc.{js,cjs} 文件使用以下规则,其它文件使用 standard 规则
    {
      env: {
        node: true, // 启用node环境的全局变量
      },
      files: [
        ".eslintrc.{js,cjs}", // 文件
      ],
      parserOptions: {
        sourceType: "script",
      },
      rules: {
        // 文件对应的检查规则
        quotes: [2, "double"],
        indent: ["error", 4],
        "quote-props": ["error", "always"],
      },
    },
  ],
};

# 5、rules 节点

TIP

我们可以在 rules 节点中配置相关的规则,这些规则会覆盖 extends 节点中指定的规则

要改变规则的设置,你必须把规则 ID 设置为这些值之一:

  • "off"0 - 关闭规则
  • "warn"1 - 启用并视作警告(不影响退出)
  • "error"2 - 启用并视作错误(触发时退出代码为 1)

ESLint 的所有规则参考:规则参考 (opens new window)

module.exports = {
  env: {
    // 环境全局变量
    browser: true,
    commonjs: true,
    es2021: true,
  },
  extends: "standard", // 栓查规则包
  overrides: [], //覆盖
  parserOptions: {
    //
    ecmaVersion: "latest",
  },
  rules: {
    // 文件对应的检查规则 ,会覆盖standard规则包中对应规则
    quotes: [2, "double"],
    indent: ["error", 4],
    "quote-props": ["error", "always"],
    "no-var": 0,
  },
};

常见规则

"no-alert": 0,//禁止使用alert confirm prompt
"no-array-constructor": 2,//禁止使用数组构造器
"no-bitwise": 0,//禁止使用按位运算符
"no-caller": 1,//禁止使用arguments.caller或arguments.callee
"no-catch-shadow": 2,//禁止catch子句参数与外部作用域变量同名
"no-class-assign": 2,//禁止给类赋值
"no-cond-assign": 2,//禁止在条件表达式中使用赋值语句
"no-console": 2,//禁止使用console
"no-const-assign": 2,//禁止修改const声明的变量
"no-constant-condition": 2,//禁止在条件中使用常量表达式 if(true) if(1)
"no-continue": 0,//禁止使用continue
"no-control-regex": 2,//禁止在正则表达式中使用控制字符
"no-debugger": 2,//禁止使用debugger
"no-delete-var": 2,//不能对var声明的变量使用delete操作符
"no-div-regex": 1,//不能使用看起来像除法的正则表达式/=foo/
"no-dupe-keys": 2,//在创建对象字面量时不允许键重复 {a:1,a:1}
"no-dupe-args": 2,//函数参数不能重复
"no-duplicate-case": 2,//switch中的case标签不能重复
"no-else-return": 2,//如果if语句里面有return,后面不能跟else语句
"no-empty": 2,//块语句中的内容不能为空
"no-empty-character-class": 2,//正则表达式中的[]内容不能为空
"no-empty-label": 2,//禁止使用空label
"no-eq-null": 2,//禁止对null使用==或!=运算符
"no-eval": 1,//禁止使用eval
"no-ex-assign": 2,//禁止给catch语句中的异常参数赋值
"no-extend-native": 2,//禁止扩展native对象
"no-extra-bind": 2,//禁止不必要的函数绑定
"no-extra-boolean-cast": 2,//禁止不必要的bool转换
"no-extra-parens": 2,//禁止非必要的括号
"no-extra-semi": 2,//禁止多余的冒号
"no-fallthrough": 1,//禁止switch穿透
"no-floating-decimal": 2,//禁止省略浮点数中的0 .5 3.
"no-func-assign": 2,//禁止重复的函数声明
"no-implicit-coercion": 1,//禁止隐式转换
"no-implied-eval": 2,//禁止使用隐式eval
"no-inline-comments": 0,//禁止行内备注
"no-inner-declarations": [2, "functions"],//禁止在块语句中使用声明(变量或函数)
"no-invalid-regexp": 2,//禁止无效的正则表达式
"no-invalid-this": 2,//禁止无效的this,只能用在构造器,类,对象字面量
"no-irregular-whitespace": 2,//不能有不规则的空格
"no-iterator": 2,//禁止使用__iterator__ 属性
"no-label-var": 2,//label名不能与var声明的变量名相同
"no-labels": 2,//禁止标签声明
"no-lone-blocks": 2,//禁止不必要的嵌套块
"no-lonely-if": 2,//禁止else语句内只有if语句
"no-loop-func": 1,//禁止在循环中使用函数(如果没有引用外部变量不形成闭包就可以)
"no-mixed-requires": [0, false],//声明时不能混用声明类型
"no-mixed-spaces-and-tabs": [2, false],//禁止混用tab和空格
"linebreak-style": [0, "windows"],//换行风格
"no-multi-spaces": 1,//不能用多余的空格
"no-multi-str": 2,//字符串不能用\换行
"no-multiple-empty-lines": [1, {"max": 2}],//空行最多不能超过2行
"no-native-reassign": 2,//不能重写native对象
"no-negated-in-lhs": 2,//in 操作符的左边不能有!
"no-nested-ternary": 0,//禁止使用嵌套的三目运算
"no-new": 1,//禁止在使用new构造一个实例后不赋值
"no-new-func": 1,//禁止使用new Function
"no-new-object": 2,//禁止使用new Object()
"no-new-require": 2,//禁止使用new require
"no-new-wrappers": 2,//禁止使用new创建包装实例,new String new Boolean new Number
"no-obj-calls": 2,//不能调用内置的全局对象,比如Math() JSON()
"no-octal": 2,//禁止使用八进制数字
"no-octal-escape": 2,//禁止使用八进制转义序列
"no-param-reassign": 2,//禁止给参数重新赋值
"no-path-concat": 0,//node中不能使用__dirname或__filename做路径拼接
"no-plusplus": 0,//禁止使用++,--
"no-process-env": 0,//禁止使用process.env
"no-process-exit": 0,//禁止使用process.exit()
"no-proto": 2,//禁止使用__proto__属性
"no-redeclare": 2,//禁止重复声明变量
"no-regex-spaces": 2,//禁止在正则表达式字面量中使用多个空格 /foo bar/
"no-restricted-modules": 0,//如果禁用了指定模块,使用就会报错
"no-return-assign": 1,//return 语句中不能有赋值表达式
"no-script-url": 0,//禁止使用javascript:void(0)
"no-self-compare": 2,//不能比较自身
"no-sequences": 0,//禁止使用逗号运算符
"no-shadow": 2,//外部作用域中的变量不能与它所包含的作用域中的变量或参数同名
"no-shadow-restricted-names": 2,//严格模式中规定的限制标识符不能作为声明时的变量名使用
"no-spaced-func": 2,//函数调用时 函数名与()之间不能有空格
"no-sparse-arrays": 2,//禁止稀疏数组, [1,,2]
"no-sync": 0,//nodejs 禁止同步方法
"no-ternary": 0,//禁止使用三目运算符
"no-trailing-spaces": 1,//一行结束后面不要有空格
"no-this-before-super": 0,//在调用super()之前不能使用this或super
"no-throw-literal": 2,//禁止抛出字面量错误 throw "error";
"no-undef": 1,//不能有未定义的变量
"no-undef-init": 2,//变量初始化时不能直接给它赋值为undefined
"no-undefined": 2,//不能使用undefined
"no-unexpected-multiline": 2,//避免多行表达式
"no-underscore-dangle": 1,//标识符不能以_开头或结尾
"no-unneeded-ternary": 2,//禁止不必要的嵌套 var isYes = answer === 1 ? true : false;
"no-unreachable": 2,//不能有无法执行的代码
"no-unused-expressions": 2,//禁止无用的表达式
"no-unused-vars": [2, {"vars": "all", "args": "after-used"}],//不能有声明后未被使用的变量或参数
"no-use-before-define": 2,//未定义前不能使用
"no-useless-call": 2,//禁止不必要的call和apply
"no-void": 2,//禁用void操作符
"no-var": 0,//禁用var,用let和const代替
"no-warning-comments": [1, { "terms": ["todo", "fixme", "xxx"], "location": "start" }],//不能有警告备注
"no-with": 2,//禁用with
"array-bracket-spacing": [2, "never"],//是否允许非空数组里面有多余的空格
"arrow-parens": 0,//箭头函数用小括号括起来
"arrow-spacing": 0,//=>的前/后括号
"accessor-pairs": 0,//在对象中使用getter/setter
"block-scoped-var": 0,//块语句中使用var
"brace-style": [1, "1tbs"],//大括号风格
"callback-return": 1,//避免多次调用回调什么的
"camelcase": 2,//强制驼峰法命名
"comma-dangle": [2, "never"],//对象字面量项尾不能有逗号
"comma-spacing": 0,//逗号前后的空格
"comma-style": [2, "last"],//逗号风格,换行时在行首还是行尾
"complexity": [0, 11],//循环复杂度
"computed-property-spacing": [0, "never"],//是否允许计算后的键名什么的
"consistent-return": 0,//return 后面是否允许省略
"consistent-this": [2, "that"],//this别名
"constructor-super": 0,//非派生类不能调用super,派生类必须调用super
"curly": [2, "all"],//必须使用 if(){} 中的{}
"default-case": 2,//switch语句最后必须有default
"dot-location": 0,//对象访问符的位置,换行的时候在行首还是行尾
"dot-notation": [0, { "allowKeywords": true }],//避免不必要的方括号
"eol-last": 0,//文件以单一的换行符结束
"eqeqeq": 2,//必须使用全等
"func-names": 0,//函数表达式必须有名字
"func-style": [0, "declaration"],//函数风格,规定只能使用函数声明/函数表达式
"generator-star-spacing": 0,//生成器函数*的前后空格
"guard-for-in": 0,//for in循环要用if语句过滤
"handle-callback-err": 0,//nodejs 处理错误
"id-length": 0,//变量名长度
"indent": [2, 4],//缩进风格
"init-declarations": 0,//声明时必须赋初值
"key-spacing": [0, { "beforeColon": false, "afterColon": true }],//对象字面量中冒号的前后空格
"lines-around-comment": 0,//行前/行后备注
"max-depth": [0, 4],//嵌套块深度
"max-len": [0, 80, 4],//字符串最大长度
"max-nested-callbacks": [0, 2],//回调嵌套深度
"max-params": [0, 3],//函数最多只能有3个参数
"max-statements": [0, 10],//函数内最多有几个声明
"new-cap": 2,//函数名首行大写必须使用new方式调用,首行小写必须用不带new方式调用
"new-parens": 2,//new时必须加小括号
"newline-after-var": 2,//变量声明后是否需要空一行
"object-curly-spacing": [0, "never"],//大括号内是否允许不必要的空格
"object-shorthand": 0,//强制对象字面量缩写语法
"one-var": 1,//连续声明
"operator-assignment": [0, "always"],//赋值运算符 += -=什么的
"operator-linebreak": [2, "after"],//换行时运算符在行尾还是行首
"padded-blocks": 0,//块语句内行首行尾是否要空行
"prefer-const": 0,//首选const
"prefer-spread": 0,//首选展开运算
"prefer-reflect": 0,//首选Reflect的方法
"quotes": [1, "single"],//引号类型 "" ''
"quote-props":[2, "always"],//对象字面量中的属性名是否强制双引号
"radix": 2,//parseInt必须指定第二个参数
"id-match": 0,//命名检测
"require-yield": 0,//生成器函数必须有yield
"semi": [2, "always"],//语句强制分号结尾
"semi-spacing": [0, {"before": false, "after": true}],//分号前后空格
"sort-vars": 0,//变量声明时排序
"space-after-keywords": [0, "always"],//关键字后面是否要空一格
"space-before-blocks": [0, "always"],//不以新行开始的块{前面要不要有空格
"space-before-function-paren": [0, "always"],//函数定义时括号前面要不要有空格
"space-in-parens": [0, "never"],//小括号里面要不要有空格
"space-infix-ops": 0,//中缀操作符周围要不要有空格
"space-return-throw-case": 2,//return throw case后面要不要加空格
"space-unary-ops": [0, { "words": true, "nonwords": false }],//一元运算符的前/后要不要加空格
"spaced-comment": 0,//注释风格要不要有空格什么的
"strict": 2,//使用严格模式
"use-isnan": 2,//禁止比较时使用NaN,只能用isNaN()
"valid-jsdoc": 0,//jsdoc规则
"valid-typeof": 2,//必须使用合法的typeof的值
"vars-on-top": 2,//var必须放在作用域顶部
"wrap-iife": [2, "inside"],//立即执行函数表达式的小括号风格
"wrap-regex": 0,//正则表达式字面量用小括号包起来
"yoda": [2, "never"]//禁止尤达条件

# 5、parserOptions 节点

TIP

ESLint 允许你指定你想要支持的 JavaScript 语言选项。默认情况下,ESLint 希望使用 ECMAScript 5 语法。

你可以通过使用解析器选项来覆盖这一设置,以实现对其他 ECMAScript 版本以及 JSX 的支持。

{
    "parserOptions": {
        "ecmaVersion": 6   // 启用 ES6 语法
    }
}

注:

ecmaVersion - 设置为 3、5(默认)、6、7、8、9、10、11、12 或 13,以指定你要使用的 ECMAScript 语法的版本。

你也可以设置为 2015(6)、2016(7)、2017(8)、2018(9)、2019(10)、2020(11)、2021(12)或 2022(13)来使用基于年份的命名。你也可以设置 "latest" 来使用受支持的最新版本。

具体配置参考官方:指定解析器选项 (opens new window)

# 三、Prettier 代码格式化

TIP

Prettier 是一个代码格式化工具。

我们通过一个简单的代码示例来帮助大家学习如何使用 Prettier 插件。

# 1、创建项目

执行以下命令,初始化package.json文件

npm init -y

新建src/index.js文件,内容如下:

const obj = {
  username: "admin",
  password: "123456",
};

const a = 1;
const b = 2;
const arr = [1, 2, 3];

# 2、安装 Prettier

执行以下命令安装 Prettier

npm install --save-dev --save-exact prettier

# 3、添加配置

TIP

在项目根目录下新建.prettierrc.json文件,该文件为Prettier插件的配置文件,然后添加相关配置。

配置示例

{
  "semi": false,  // 仅在特列情况下在代码尾部加分号,其它都不加
  "tabWidth": 2, // 指定每个缩进级别的空格数2
  "singleQuote": true,  // 使用单引号
  "printWidth": 100,   // 代码换行的长度
  "trailingComma": "none"  // 没有尾随逗号
}

更多配置查阅 prettier-配置选项 (opens new window),以下为部分配置示例

{
  // 一行的字符数,如果超过会进行换行,默认为80
	printWidth: 80,
	// tab缩进大小,默认为2
	tabWidth: 2,
	// 使用tab缩进,默认false
	useTabs: true,
	// 不使用分号, 默认true, true表示添加
	semi: false,
	// 使用单引号, 默认false(在jsx中配置无效, 默认都是双引号)
	singleQuote: true,
	// 行尾逗号,默认none,可选 none|es5|all
	// es5 包括es5中的数组、对象
	// all 包括函数对象等所有可选
	trailingComma: 'es5',
	// 对象中的空格 默认true
	// true: { foo: bar }
	// false: {foo: bar}
	bracketSpacing: true,
	// JSX标签闭合位置 默认false
	// false: <div
	//          className=""
	//          style={{}}
	//       >
	// true: <div
	//          className=""
	//          style={{}} >
	jsxBracketSameLine: true,
	// 箭头函数参数括号 默认avoid 可选 avoid| always
	// avoid 能省略括号的时候就省略 例如x => x
	// always 总是有括号
	arrowParens: 'avoid',
	endOfLine: 'auto', // 结尾是 \n \r \n\r auto

}

# 4、代码格式化

执行以下命令,调用Prettier来格式化代码

npx prettier src/index.js --write  # 只格式化src/index.js文件
# 或
npx prettier src/  --write  # 格式化 src目录下所有文件
# 或
npx prettier . --write     # 格式化整个项目

最终格式化后src/index.js文件内容如下:

const obj = {
  username: "admin",
  password: "123456",
};

const a = 1;
const b = 2;
const arr = [1, 2, 3];

# 四、VueUse

TIP

VueUse 是一款基于组合式 API (opens new window)的函数集合,到目前为止大概有 200 多个函数。

VusUse 中文文档:https://www.vueusejs.com (opens new window)

# 1、VueUse 基本使用

  • 使用 VueUse 提供的函数前,需要先执行以下命令安装 VueUse 核心包
npm i @vueuse/core
  • 然后在@vueuse/core中导入你需要的函数 (opens new window),这里以useToggle函数为例来讲解

  • useToggle函数用来实现对某个响应式变量布尔值的切换,主要用来实现toggle切换

<script setup lang="ts">
  import { useToggle } from "@vueuse/core";
  // isShow=ref(false) toggle用来切换isShow的布尔值
  const [isShow, toggle] = useToggle(false);
</script>

<template>
  <button @click="toggle()">切换</button> |
  <button @click="toggle(false)">隐藏</button> |
  <button @click="toggle(true)">显示</button>
  <div class="box" v-if="isShow">box.....</div>
</template>

最终效果如下:

GIF2023-10-1222-19-42

# 2、useStorage 响应式本地存储

TIP

useStorage 用于实现响应式本地存储,当数据发生变会时,页面用到数据的地址方会自动更新,同时也会更新本地存储。

也可参考 VueUse 官方应用 (opens new window)

<script setup lang="ts">
  import { useStorage } from "@vueuse/core";

  // 初始值
  const theDefault = [
    {
      id: 1,
      keyword: "奶茶",
    },
    {
      id: 2,
      keyword: "葡萄",
    },
    {
      id: 3,
      keyword: "口红",
    },
  ];
  // historyList为theDefault的响应式 , historyList=ref(theDefault) 当值被修改时,本地存储中也会更新
  // theDefault 为默认值
  const historyList = useStorage("historyList", theDefault);

  // 添加
  const add = () => {
    historyList.value.push({
      id: Date.now(),
      keyword: "苹果",
    });
  };
  // 移除
  const remove = () => {
    historyList.value.shift();
  };
</script>
<template>
  <button @click="add">添加数据</button> |
  <button @click="remove">移除数据</button>
  <ul>
    <li v-for="item in historyList" :key="item.id">{{ item.keyword }}</li>
  </ul>
</template>

GIF2023-10-1222-55-22

上次更新时间: 10/16/2023, 1:52:39 AM

大厂最新技术学习分享群

大厂最新技术学习分享群

微信扫一扫进群,获取资料

X