├── .eslintignore
├── .eslintrc
├── .gitignore
├── .husky
├── commit-msg
└── pre-commit
├── .lintstagedrc.js
├── .ls-lint.yml
├── .npmrc
├── .prettierignore
├── .stylelintignore
├── .vscode
└── settings.json
├── commitlint.config.js
├── example
├── app.vue
├── index.html
├── main.ts
├── package.json
└── vite.config.js
├── package.json
├── packages
├── components
│ ├── button-group
│ │ ├── index.ts
│ │ └── src
│ │ │ └── button-group.vue
│ ├── button
│ │ ├── index.ts
│ │ └── src
│ │ │ ├── button.ts
│ │ │ ├── button.vue
│ │ │ └── interface.d.ts
│ ├── components.ts
│ ├── index.ts
│ └── package.json
├── eslint-config
│ ├── eslint.rules.js
│ ├── index.js
│ ├── package.json
│ ├── ts.rules.js
│ └── vue.rules.js
├── theme-chalk
│ ├── package.json
│ └── src
│ │ ├── button-group.scss
│ │ ├── button.scss
│ │ ├── common
│ │ ├── color.scss
│ │ ├── transition.scss
│ │ └── var.scss
│ │ ├── index.scss
│ │ └── mixins
│ │ ├── _button.scss
│ │ ├── config.scss
│ │ ├── function.scss
│ │ ├── mixins.scss
│ │ └── utils.scss
└── utils
│ ├── index.ts
│ ├── package.json
│ └── vue
│ ├── index.ts
│ ├── install.ts
│ └── typescript.ts
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── prettier.config.js
├── stylelint.config.js
├── tsconfig.json
└── typings
└── vue-shim.d.ts
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/*
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "extends": ["@brain-ui/eslint-config"]
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Editor directories and files
2 | .idea
3 |
4 | # Package Manager
5 | node_modules
6 | .pnpm-debug.log*
7 |
8 | # System
9 | .DS_Store
10 |
11 | # Bundle
12 | dist
13 | coverage
14 |
15 | # local env files
16 | *.local
17 | .eslintcache
18 | tmp
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx commitlint --edit $1
5 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx lint-staged
5 |
--------------------------------------------------------------------------------
/.lintstagedrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
3 | '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
4 | 'package.json': ['prettier --write'],
5 | '*.vue': ['prettier --write', 'eslint --fix'],
6 | 'packages/theme-chalk/src/**/*.{scss,css}': ['stylelint --fix --custom-syntax postcss-scss', 'prettier --write'],
7 | '*.md': ['prettier --write']
8 | };
9 |
--------------------------------------------------------------------------------
/.ls-lint.yml:
--------------------------------------------------------------------------------
1 | ls:
2 | packages/components/*:
3 | .dir: kebab-case
4 | .vue: kebab-case
5 | .js: kebab-case
6 | .ts: kebab-case
7 | .json: kebab-case
8 | .d.ts: kebab-case
9 | .tsx: kebab-case
10 |
11 | ignore:
12 | - .git
13 | - .vscode
14 | - node_modules
15 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | shamefully-hoist=true
2 | strict-peer-dependencies=false
3 | shell-emulator=true
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules/*
--------------------------------------------------------------------------------
/.stylelintignore:
--------------------------------------------------------------------------------
1 | /dist/*
2 | /public/*
3 | /example/*
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "eslint.validate": ["html", "vue", "javascript", "jsx"],
3 | "emmet.syntaxProfiles": {
4 | "vue-html": "html",
5 | "vue": "html"
6 | },
7 | "editor.tabSize": 2,
8 | "eslint.alwaysShowStatus": true,
9 | "eslint.quiet": true,
10 | "editor.codeActionsOnSave": {
11 | "source.fixAll.eslint": true,
12 | "source.fixAll": true,
13 | "source.fixAll.stylelint": true
14 | },
15 | "stylelint.customSyntax": "postcss-scss",
16 | "stylelint.validate": [
17 | "css",
18 | "less",
19 | "postcss",
20 | "scss",
21 | "vue",
22 | "sass"
23 | ],
24 | }
25 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | /* https://commitlint.js.org/#/reference-rules */
2 | module.exports = {
3 | ignores: [commit => commit.includes('init')],
4 | extends: ['@commitlint/config-conventional'],
5 | rules: {
6 | 'body-leading-blank': [2, 'always'],
7 | 'footer-leading-blank': [1, 'always'],
8 | 'header-max-length': [2, 'always', 108],
9 | 'subject-empty': [2, 'never'],
10 | 'type-empty': [2, 'never'],
11 | 'subject-case': [0]
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/example/app.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | button
4 | button
5 | button
6 | button
7 | button
8 | button
9 |
10 |
11 |
12 | 按钮尺寸
13 | 按钮尺寸
14 | 按钮尺寸
15 | 按钮尺寸
16 | 按钮尺寸
17 |
18 |
19 | 朴素按钮
20 | 椭圆
21 | 禁止
22 | 圆
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue';
2 | import App from './app.vue';
3 | import '@brain-ui/theme-chalk/src/index.scss';
4 | import BrainUi from '@brain-ui/components';
5 |
6 | const app = createApp(App);
7 | app.use(BrainUi);
8 |
9 | // app.use(BrainButton)
10 | // app.use(BrainButtonGroup)
11 | app.mount('#app');
12 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "vite"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "@vitejs/plugin-vue": "^3.1.2",
14 | "vite": "^3.1.8",
15 | "vite-plugin-eslint": "^1.8.1",
16 | "vite-plugin-vue-setup-extend": "^0.4.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/example/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import vue from '@vitejs/plugin-vue';
3 | import VueSetupExtend from 'vite-plugin-vue-setup-extend'; //用于给setup script组建增加name属性
4 | import viteEslint from 'vite-plugin-eslint';
5 |
6 | export default defineConfig({
7 | plugins: [
8 | vue(),
9 | /* https://www.npmjs.com/package/vite-plugin-eslint */
10 | viteEslint(),
11 | VueSetupExtend()
12 | ]
13 | });
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "brain-ui",
3 | "version": "0.0.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "pnpm -C example dev",
8 | "clear": "rimraf dist",
9 | "clear:cache": "rimraf node_modules/.cache/ rimraf node_modules/.vite",
10 | "clear:lib": "rimraf node_modules",
11 | "lint:fix": "eslint . --fix",
12 | "lint:eslint": "eslint .",
13 | "lint:prettier": "prettier --write .",
14 | "lint:css": "stylelint 'packages/theme-chalk/src/**/*.scss' --fix --custom-syntax postcss-scss",
15 | "lint:ls-lint": "ls-lint",
16 | "lint:staged": "lint-staged",
17 | "reinstall": "rimraf pnpm-lock.yarm && rimraf node_modules && pnpm install",
18 | "prepare": "husky install",
19 | "postinstall": "npx husky install",
20 | "commit": "git-cz"
21 | },
22 | "keywords": [],
23 | "author": "SNine ",
24 | "license": "ISC",
25 | "config": {
26 | "commitizen": {
27 | "path": "cz-conventional-changelog"
28 | }
29 | },
30 | "devDependencies": {
31 | "@commitlint/cli": "^17.2.0",
32 | "@commitlint/config-conventional": "^17.2.0",
33 | "@ls-lint/ls-lint": "^1.11.2",
34 | "@typescript-eslint/eslint-plugin": "^5.42.0",
35 | "@typescript-eslint/parser": "^5.42.0",
36 | "commitizen": "^4.2.5",
37 | "cz-conventional-changelog": "^3.3.0",
38 | "eslint": "^8.26.0",
39 | "eslint-config-prettier": "^8.5.0",
40 | "eslint-plugin-prettier": "^4.2.1",
41 | "eslint-plugin-vue": "^9.7.0",
42 | "husky": "^8.0.2",
43 | "lint-staged": "^13.0.3",
44 | "postcss-scss": "^4.0.5",
45 | "prettier": "^2.7.1",
46 | "rimraf": "^3.0.2",
47 | "sass": "^1.55.0",
48 | "stylelint": "^14.14.1",
49 | "stylelint-config-prettier": "^9.0.4",
50 | "stylelint-config-standard": "^29.0.0",
51 | "stylelint-order": "^5.0.0",
52 | "stylelint-scss": "^4.3.0",
53 | "typescript": "^4.8.4",
54 | "vue": "^3.2.36"
55 | },
56 | "dependencies": {
57 | "@brain-ui/components": "workspace:^0.0.1",
58 | "@brain-ui/eslint-config": "workspace:^0.0.1",
59 | "@brain-ui/theme-chalk": "workspace:^0.0.1",
60 | "@brain-ui/utils": "workspace:^0.0.1"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/packages/components/button-group/index.ts:
--------------------------------------------------------------------------------
1 | import buttonGroup from './src/button-group.vue';
2 | import { withInstall } from '@brain-ui/utils';
3 |
4 | export const BrainButtonGroup = withInstall(buttonGroup);
5 |
6 | export default BrainButtonGroup;
7 |
--------------------------------------------------------------------------------
/packages/components/button-group/src/button-group.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
--------------------------------------------------------------------------------
/packages/components/button/index.ts:
--------------------------------------------------------------------------------
1 | import button from './src/button.vue';
2 |
3 | import { withInstall } from '@brain-ui/utils';
4 |
5 | export const BrainButton = withInstall(button);
6 |
7 | export default BrainButton;
8 |
--------------------------------------------------------------------------------
/packages/components/button/src/button.ts:
--------------------------------------------------------------------------------
1 | import type { ExtractPropTypes, PropType } from 'vue';
2 | import type { ButtonNativeType, ButtonSizeType, ButtonType } from './interface';
3 |
4 | export const Props = {
5 | type: {
6 | type: String as PropType,
7 | default: (): ButtonType => 'default',
8 | validator(value: ButtonType): boolean {
9 | return (['default', 'primary', 'success', 'info', 'danger', 'warning'] as const).includes(value);
10 | }
11 | },
12 | size: {
13 | type: String as PropType,
14 | validator(value: ButtonSizeType): boolean {
15 | return (['default', 'medium', 'small', 'mini', 'tiny'] as const).includes(value);
16 | }
17 | },
18 | plain: {
19 | type: Boolean,
20 | default: (): boolean => false
21 | },
22 | round: {
23 | type: Boolean,
24 | default: (): boolean => false
25 | },
26 | circle: {
27 | type: Boolean,
28 | default: (): boolean => false
29 | },
30 | loading: {
31 | type: Boolean,
32 | default: (): boolean => false
33 | },
34 | disabled: {
35 | type: Boolean,
36 | default: (): boolean => false
37 | },
38 | icon: {
39 | type: String,
40 | default: (): String => ''
41 | },
42 | autoFocus: {
43 | type: Boolean,
44 | default: (): boolean => false
45 | },
46 | nativeType: {
47 | type: String as PropType,
48 | default: (): ButtonNativeType => 'button',
49 | validator(value): boolean {
50 | return (['button', 'submit', 'reset'] as const).includes(value);
51 | }
52 | }
53 | };
54 |
55 | export const Emits = {
56 | click: (evt: MouseEvent): MouseEvent => evt
57 | };
58 |
59 | export type ButtonPropsType = ExtractPropTypes;
60 |
--------------------------------------------------------------------------------
/packages/components/button/src/button.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
40 |
--------------------------------------------------------------------------------
/packages/components/button/src/interface.d.ts:
--------------------------------------------------------------------------------
1 | import type { ButtonHTMLAttributes } from 'vue';
2 |
3 | export type ButtonSizeType = 'default' | 'medium' | 'small' | 'mini' | 'tiny';
4 |
5 | export type ButtonType = 'default' | 'primary' | 'success' | 'info' | 'danger' | 'warning';
6 |
7 | export type ButtonNativeType = NonNullable;
8 |
--------------------------------------------------------------------------------
/packages/components/components.ts:
--------------------------------------------------------------------------------
1 | export { BrainButton } from './button';
2 | export { BrainButtonGroup } from './button-group';
3 |
--------------------------------------------------------------------------------
/packages/components/index.ts:
--------------------------------------------------------------------------------
1 | import type { App } from 'vue';
2 | import * as components from './components';
3 | import { version } from './package.json';
4 |
5 | const install = function (app: App): void {
6 | Object.entries(components).forEach(([key, value]) => {
7 | app.component(key, value);
8 | });
9 | };
10 |
11 | export default {
12 | install,
13 | version
14 | };
15 |
--------------------------------------------------------------------------------
/packages/components/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@brain-ui/components",
3 | "version": "0.0.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC"
12 | }
13 |
--------------------------------------------------------------------------------
/packages/eslint-config/eslint.rules.js:
--------------------------------------------------------------------------------
1 | /* eslint配置规则 https://eslint.org/docs/latest/rules/ */
2 | module.exports = {
3 | 'prettier/prettier': 'error',
4 | 'arrow-body-style': 'off',
5 | 'prefer-arrow-callback': 'off',
6 | 'no-console': 2,
7 | // 不允许不必要的转义字符 https://eslint.org/docs/latest/rules/no-useless-escape
8 | 'no-useless-escape': 'off',
9 | //
10 | 'comma-dangle': 'off',
11 | // 禁止使用 var https://eslint.org/docs/latest/rules/no-var#rule-details
12 | 'no-var': 'error',
13 | // 使用单引号 https://eslint.org/docs/latest/rules/quotes#version
14 | quotes: ['error', 'single'],
15 | // 禁止分号 https://eslint.org/docs/latest/rules/semi#rule-details
16 | // semi: 'error',
17 | // 禁止 debugger https://eslint.org/docs/latest/rules/no-debugger#rule-details
18 | 'no-debugger': 'error',
19 | // 禁止未使用的变量 https://eslint.org/docs/latest/rules/no-unused-vars#rule-details
20 | 'no-unused-vars': 'error',
21 | // 不允许使用未声明的变量 https://eslint.org/docs/latest/rules/no-undef
22 | 'no-undef': 'off',
23 | // 函数括号前的空格 https://eslint.org/docs/latest/rules/space-before-function-paren
24 | 'space-before-function-paren': 'off',
25 | // 禁止多个空行 https://eslint.org/docs/latest/rules/no-multiple-empty-lines#rule-details
26 | 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0, maxBOF: 0 }],
27 | // 在文件末尾要求或禁止换行 https://eslint.org/docs/latest/rules/eol-last#rule-details
28 | 'eol-last': 'error',
29 | // 禁止所有选项卡 https://eslint.org/docs/latest/rules/no-tabs#rule-details
30 | 'no-tabs': 'error',
31 | 'default-param-last': 'off'
32 | };
33 |
--------------------------------------------------------------------------------
/packages/eslint-config/index.js:
--------------------------------------------------------------------------------
1 | const eslintRules = require('./eslint.rules');
2 | const tsRules = require('./ts.rules');
3 | const vueRules = require('./vue.rules');
4 |
5 | module.exports = {
6 | env: {
7 | browser: true,
8 | es2021: true,
9 | node: true
10 | },
11 | /* 'plugin:prettier/recommended' 可手动配置 */
12 | extends: ['plugin:vue/vue3-essential', 'prettier', 'plugin:@typescript-eslint/recommended'],
13 | overrides: [],
14 | parser: 'vue-eslint-parser',
15 | parserOptions: {
16 | ecmaVersion: 'latest',
17 | sourceType: 'module',
18 | parser: '@typescript-eslint/parser'
19 | },
20 | plugins: ['vue', '@typescript-eslint', 'prettier'],
21 | rules: {
22 | ...eslintRules,
23 | ...tsRules,
24 | ...vueRules
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/packages/eslint-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@brain-ui/eslint-config",
3 | "version": "0.0.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "SNine ",
11 | "license": "MIT"
12 | }
13 |
--------------------------------------------------------------------------------
/packages/eslint-config/ts.rules.js:
--------------------------------------------------------------------------------
1 | /* ts配置规则 https://typescript-eslint.io/rules */
2 | module.exports = {
3 | // 规定数组类型定义方式 https://typescript-eslint.io/rules/array-type
4 | '@typescript-eslint/array-type': 'error',
5 | // 禁止使用大写 String、Number 定义类型 https://typescript-eslint.io/rules/ban-types
6 | '@typescript-eslint/ban-types': 'off', // beta
7 | // 不允许尾随逗号 https://typescript-eslint.io/rules/comma-dangle
8 | '@typescript-eslint/comma-dangle': 'error',
9 | // 强制使用 interface 定义类型 https://typescript-eslint.io/rules/consistent-type-definitions
10 | '@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
11 | // 统一导出规则 https://typescript-eslint.io/rules/consistent-type-exports
12 | // '@typescript-eslint/consistent-type-exports': 'error',
13 | // 自定义对象类型样式 https://typescript-eslint.io/rules/consistent-indexed-object-style
14 | '@typescript-eslint/consistent-indexed-object-style': ['warn', 'record'],
15 | // !禁止使用后缀运算符的非空断言 https://typescript-eslint.io/rules/no-non-null-assertion/
16 | '@typescript-eslint/no-non-null-assertion': 'error',
17 | // 强制一致地使用类型导入 https://typescript-eslint.io/rules/consistent-type-imports
18 | '@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports' }],
19 | // 禁止未使用的变量 https://typescript-eslint.io/rules/no-unused-vars
20 | '@typescript-eslint/no-unused-vars': 'error',
21 | // 不可以有 any https://typescript-eslint.io/rules/no-explicit-any/
22 | '@typescript-eslint/no-explicit-any': 'off',
23 | // 不可以有 require https://typescript-eslint.io/rules/no-var-requires/
24 | '@typescript-eslint/no-var-requires': 'off',
25 | // 带有默认值的函数参数在最后 https://typescript-eslint.io/rules/default-param-last
26 | '@typescript-eslint/default-param-last': 'error',
27 | // 必须标记函数返回值 https://typescript-eslint.io/rules/explicit-function-return-type
28 | '@typescript-eslint/explicit-function-return-type': 'off'
29 | };
30 |
--------------------------------------------------------------------------------
/packages/eslint-config/vue.rules.js:
--------------------------------------------------------------------------------
1 | /* vue配置规则 https://eslint.vuejs.org/rules/ */
2 | module.exports = {
3 | /* 禁止在模板中使用 this https://eslint.vuejs.org/rules/this-in-template.html */
4 | 'vue/this-in-template': 'error',
5 | /* 关闭名称校验 https://eslint.vuejs.org/rules/multi-word-component-names.html */
6 | 'vue/multi-word-component-names': 'off',
7 | 'vue/max-attributes-per-line': ['error', { singleline: { max: 30 }, multiline: { max: 30 } }],
8 | /* 组件标签顺序 https://eslint.vuejs.org/rules/component-tags-order.html */
9 | 'vue/component-tags-order': ['error', { order: ['template', 'script', 'style'] }],
10 | /* 只允许使用ts类型的script https://eslint.vuejs.org/rules/block-lang.html */
11 | 'vue/block-lang': ['error', { script: { lang: 'ts' } }],
12 | /* 只允许使用 setup script类型的语法 https://eslint.vuejs.org/rules/component-api-style.html */
13 | 'vue/component-api-style': ['error', ['script-setup', 'composition']],
14 | /* 自定义事件强制使用中划线连接 https://eslint.vuejs.org/rules/custom-event-name-casing.html */
15 | 'vue/custom-event-name-casing': ['error', 'kebab-case', { ignores: [] }],
16 | /* 禁止使用 v-html https://eslint.vuejs.org/rules/no-v-html.html */
17 | 'vue/no-v-html': 'error',
18 | /* bind绑定时能简写就直接简写 https://eslint.vuejs.org/rules/prefer-true-attribute-shorthand.html */
19 | 'vue/prefer-true-attribute-shorthand': 'error',
20 | /* 模板中未使用的组建不允许注册 https://eslint.vuejs.org/rules/no-unused-components.html */
21 | 'vue/no-unused-components': 'error',
22 | /* 单标签禁止改写成双标签 https://eslint.vuejs.org/rules/html-self-closing.html */
23 | 'vue/html-self-closing': 'off',
24 | /* 强制标签闭合 https://eslint.vuejs.org/rules/html-end-tags.html */
25 | 'vue/html-end-tags': 'error',
26 | /* 模板缩进规则 */
27 | 'vue/html-indent': ['error', 2, { attribute: 1, baseIndent: 1, closeBracket: 0, alignAttributesVertically: true }],
28 | /* 模板中使用组建必须使用中划线小写形式 https://eslint.vuejs.org/rules/component-name-in-template-casing.html */
29 | 'vue/component-name-in-template-casing': ['error', 'kebab-case', { registeredComponentsOnly: false }],
30 | // 对模板中的自定义组件强制执行属性命名样式 https://eslint.vuejs.org/rules/attribute-hyphenation.html#vue-attribute-hyphenation
31 | 'vue/attribute-hyphenation': 'error',
32 | // Prop 名称强制使用特定大小写 https://eslint.vuejs.org/rules/prop-name-casing.html
33 | 'vue/prop-name-casing': 'error',
34 | // 强制执行 v-on 事件命名样式 https://eslint.vuejs.org/rules/v-on-event-hyphenation.html
35 | 'vue/v-on-event-hyphenation': 'error',
36 | // 不允许字段名称重复 https://eslint.vuejs.org/rules/no-dupe-keys.html
37 | 'vue/no-dupe-keys': 'error',
38 | // 禁止 v-if / v-else-if 链中的重复条件
39 | 'vue/no-dupe-v-else-if': 'error',
40 | // 不允许重复属性 https://eslint.vuejs.org/rules/no-duplicate-attributes.html
41 | 'vue/no-duplicate-attributes': [
42 | 'error',
43 | {
44 | allowCoexistClass: true,
45 | allowCoexistStyle: true
46 | }
47 | ],
48 | // 不允许 export 进入