vue规范

作者: 疑似故人归去 | 来源:发表于2022-06-10 22:52 被阅读0次

    一、代码规范

    1.1 IDE插件

    使用 Visual Studio Code 编译器,下载 ESLint Prettier - Code formatter、Stylelint 插件
    点击编译器左上角文件> 首选项> 设置>右上角编辑json文件, 去掉编译器配置中的关于格式化和规范相关的配置,使编译器读取项目中的配置文件

    {
        "breadcrumbs.enabled": true,
        "editor.renderControlCharacters": true,
        "editor.codeActionsOnSave": {
            "source.fixAll.eslint": true,
        "source.fixAll.stylelint": true
        },
        "editor.suggestSelection": "first",
        "explorer.confirmDelete": false,
        "vsicons.dontShowNewVersionMessage": true,
        "workbench.colorTheme": "Monokai",
        "explorer.compactFolders": false,
        //  #去掉代码结尾的分号
        "prettier.semi": false,
        //  #使用带引号替代双引号
        "prettier.singleQuote": true,
        //  #让函数(名)和后面的括号之间加个空格
        "javascript.format.insertSpaceBeforeFunctionParenthesis": true,
    }
    

    1.2 ESLint

    // 安装依赖
    npm install eslint babel-eslint eslint-config-standard eslint-loader eslint-plugin-html eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard eslint-plugin-vue--save-dev
    

    在项目下新建.eslintrc.js 文件
    .eslintrc.js配置

    module.exports = {
        env: {
            browser: true,
            node: true,
            es6: true,
            jest: true,
            commonjs: true,
        },
        extends: ['eslint:recommended', 'plugin:prettier/recommended', 'plugin:vue/essential'],
        parserOptions: {
            ecmaVersion: 2018,
            sourceType: 'module',
            ecmaFeatures: {
                experimentalObjectRestSpread: true,
                jsx: true,
            },
            parser: 'babel-eslint',
        },
        plugins: ['vue', 'prettier'],
        rules: {
            'prettier/prettier': 2,
            /**
             * 禁止使用debugger
             **/
            'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
            /**
             * 禁止使用console
             **/
            'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
            /**
             * 禁止使用 alert
             */
            'no-alert': process.env.NODE_ENV === 'production' ? 'error' : 'off',
            /**
             * 禁止使用tab
             **/
            'no-tabs': 'off',
            /**
             * 首行缩进
             */
            indent: 'off',
            /**
             * 禁止或强制在代码块中开括号前和闭括号后有空格
             */
            'block-spacing': 'error',
            /**
             * 禁止出现未使用过的变量
             */
            'no-unused-vars': 'error',
            /**
             * 在“function”定义的左括号前强制使用一致的间距
             */
            'space-before-function-paren': 'off',
            /**
             * 禁止空格和 tab 的混合缩进
             */
            'no-mixed-spaces-and-tabs': 'error',
            /**
             * 禁止条件表达式中出现赋值操作符
             */
            'no-cond-assign': 'error',
            /**
             * 禁止对象字面量中出现重复的 key
             */
            'no-dupe-keys': 'error',
            /**
             * 数组的方法除了 forEach 之外,回调函数必须有返回值
             */
            'array-callback-return': 'error',
            /**
             * 箭头函数体必须由大括号包裹
             * @reason 代码格式问题,最好由 Prettier 解决
             */
            'arrow-body-style': 'error',
            /**
             * 在箭头函数中的箭头前后强制保持一致的间距
             */
            'arrow-spacing': [2, { before: true, after: true }],
            /**
             * 将 var 定义的变量视为块作用域,禁止在块外使用
             * @reason 已经禁止使用 var 了
             */
            'block-scoped-var': 'error',
            /**
             * 变量名必须是 camelCase 风格的
             * @reason 很多 api 或文件名都不是 camelCase 风格的
             */
            camelcase: 'error',
            /**
             * switch 语句必须有 default
             */
            'default-case': 'error',
            /**
             * switch 语句中的 default 必须在最后
             */
            'default-case-last': 'error',
            /**
             * 必须使用 === 或 !==,禁止使用 == 或 !=
             */
            eqeqeq: 'off',
            /**
             * 属性使用双引号
             */
            'jsx-quotes': ['error', 'prefer-double'],
            /**
             * 单行注释必须写在上一行
             */
            'line-comment-position': 'error',
            'max-depth': ['error', 5],
            /**
             * 限制一个文件最多的行数
             */
            'max-lines': 'off',
            /**
             * new 后面的类名必须首字母大写
             */
            'new-cap': [
                'error',
                {
                    newIsCap: true,
                    capIsNew: false,
                    properties: true,
                },
            ],
            /**
             * 禁止对使用 const 定义的常量重新赋值
             */
            'no-const-assign': 'error',
            /**
             * 禁止解构赋值时出现同样名字的的重命名,比如 let { foo: foo } = bar;
             */
            'no-useless-rename': 'error',
            /**
             * 禁止没必要的 return
             */
            'no-useless-return': 'error',
            /**
             * 禁止使用 var
             */
            'no-var': 'error',
            /**
             * 禁止变量申明时用逗号一次申明多个
             */
            'one-var': ['error', 'never'],
            /**
             * 使用分号
             */
            semi: ['error', 'never'],
            'vue/camelcase': 'error',
            /**
             * 修复 no-unused-vars 不检查 jsx 的问题
             */
            'vue/jsx-uses-vars': 'error',
            /**
             * 组件名称必须和文件名一致
             */
            'vue/match-component-file-name': 'off',
            /**
             * 禁止出现重复的属性
             */
            'vue/no-duplicate-attributes': [
                'error',
                {
                    allowCoexistClass: false,
                    allowCoexistStyle: false,
                },
            ],
            /**
             * 禁止修改组件的 props
             */
            'vue/no-mutating-props': 'error',
            /**
             * 禁止出现语法错误
             */
            'vue/no-parsing-error': 'error',
            /**
             * 组件的 name 属性静止使用保留字
             */
            'vue/no-reserved-component-names': 'error',
            /**
             * 禁止覆盖保留字
             */
            'vue/no-reserved-keys': 'error',
            /**
             * 禁止在计算属性中对属性修改
             */
            'vue/no-side-effects-in-computed-properties': 'error',
            /**
             * 禁止 <template> 使用 key 属性
             */
            'vue/no-template-key': 'error',
            /**
             * 模版中的变量名禁止与前一个作用域重名
             */
            'vue/no-template-shadow': 'error',
            /**
             * 禁止使用未注册的组件
             */
            'vue/no-unregistered-components': 'off',
            /**
             * 当你的 vue 版本较老时,禁用还未支持的语法
             */
            'vue/no-unsupported-features': 'error',
            /**
             * 禁止定义在 components 中的组件未使用
             */
            'vue/no-unused-components': 'error',
            /**
             * v-for 指令的元素必须有 v-bind:key
             */
            'vue/require-v-for-key': 'error',
            /**
             * 禁止属性定义了却未使用
             */
            'vue/no-unused-properties': 'error',
            /**
             * 模版中已定义的变量必须使用
             */
            'vue/no-unused-vars': 'error',
            /**
             * 禁止在同一个元素上使用 v-if 和 v-for 指令
             */
            'vue/no-use-v-if-with-v-for': 'error',
            /**
             * props 必须用驼峰式
             */
            'vue/prop-name-casing': 'error',
            /**
             * 计算属性必须有返回值
             */
            'vue/return-in-computed-property': 'error',
            /**
             * vue 组件名称必须是多次,例如GoodDetail,不能是detail
             */
            'vue/multi-word-component-names': 0,
        },
    }
    

    webpack 配置:

    {
      test: /\.(js|vue)$/,
      loader: 'eslint-loader',
      enforce: 'pre',
      include: [resolve('examples'),resolve('src')],
      options: {
        formatter: require('eslint-friendly-formatter'),
        emitWarning: !config.dev.showEslintErrorsInOverlay
      }
    }
    

    详细见官方文档

    1.3 Prettier

    npm i -D prettier eslint-plugin-prettier eslint-config-prettier
    在项目下新建.prettierrc.js ,详细配置如下:

    module.exports = {
        env: {
            browser: true,
            node: true,
            es6: true,
            jest: true,
            commonjs: true,
        },
        extends: ['eslint:recommended', 'plugin:prettier/recommended', 'plugin:vue/essential'],
        parserOptions: {
            ecmaVersion: 2018,
            sourceType: 'module',
            ecmaFeatures: {
                experimentalObjectRestSpread: true,
                jsx: true,
            },
            parser: 'babel-eslint',
        },
        plugins: ['vue', 'prettier'],
        rules: {
            'prettier/prettier': 2,
            /**
             * 禁止使用debugger
             **/
            'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
            /**
             * 禁止使用console
             **/
            'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
            /**
             * 禁止使用 alert
             */
            'no-alert': process.env.NODE_ENV === 'production' ? 'error' : 'off',
            /**
             * 禁止使用tab
             **/
            'no-tabs': 'off',
            /**
             * 首行缩进
             */
            indent: 'off',
            /**
             * 禁止或强制在代码块中开括号前和闭括号后有空格
             */
            'block-spacing': 'error',
            /**
             * 禁止出现未使用过的变量
             */
            'no-unused-vars': 'error',
            /**
             * 在“function”定义的左括号前强制使用一致的间距
             */
            'space-before-function-paren': 'off',
            /**
             * 禁止空格和 tab 的混合缩进
             */
            'no-mixed-spaces-and-tabs': 'error',
            /**
             * 禁止条件表达式中出现赋值操作符
             */
            'no-cond-assign': 'error',
            /**
             * 禁止对象字面量中出现重复的 key
             */
            'no-dupe-keys': 'error',
            /**
             * 数组的方法除了 forEach 之外,回调函数必须有返回值
             */
            'array-callback-return': 'error',
            /**
             * 箭头函数体必须由大括号包裹
             * @reason 代码格式问题,最好由 Prettier 解决
             */
            'arrow-body-style': 'error',
            /**
             * 在箭头函数中的箭头前后强制保持一致的间距
             */
            'arrow-spacing': [2, { before: true, after: true }],
            /**
             * 将 var 定义的变量视为块作用域,禁止在块外使用
             * @reason 已经禁止使用 var 了
             */
            'block-scoped-var': 'error',
            /**
             * 变量名必须是 camelCase 风格的
             * @reason 很多 api 或文件名都不是 camelCase 风格的
             */
            camelcase: 'error',
            /**
             * switch 语句必须有 default
             */
            'default-case': 'error',
            /**
             * switch 语句中的 default 必须在最后
             */
            'default-case-last': 'error',
            /**
             * 必须使用 === 或 !==,禁止使用 == 或 !=
             */
            eqeqeq: 'off',
            /**
             * 属性使用双引号
             */
            'jsx-quotes': ['error', 'prefer-double'],
            /**
             * 单行注释必须写在上一行
             */
            'line-comment-position': 'error',
            'max-depth': ['error', 5],
            /**
             * 限制一个文件最多的行数
             */
            'max-lines': 'off',
            /**
             * new 后面的类名必须首字母大写
             */
            'new-cap': [
                'error',
                {
                    newIsCap: true,
                    capIsNew: false,
                    properties: true,
                },
            ],
            /**
             * 禁止对使用 const 定义的常量重新赋值
             */
            'no-const-assign': 'error',
            /**
             * 禁止解构赋值时出现同样名字的的重命名,比如 let { foo: foo } = bar;
             */
            'no-useless-rename': 'error',
            /**
             * 禁止没必要的 return
             */
            'no-useless-return': 'error',
            /**
             * 禁止使用 var
             */
            'no-var': 'error',
            /**
             * 禁止变量申明时用逗号一次申明多个
             */
            'one-var': ['error', 'never'],
            /**
             * 使用分号
             */
            semi: ['error', 'never'],
            'vue/camelcase': 'error',
            /**
             * 修复 no-unused-vars 不检查 jsx 的问题
             */
            'vue/jsx-uses-vars': 'error',
            /**
             * 组件名称必须和文件名一致
             */
            'vue/match-component-file-name': 'off',
            /**
             * 禁止出现重复的属性
             */
            'vue/no-duplicate-attributes': [
                'error',
                {
                    allowCoexistClass: false,
                    allowCoexistStyle: false,
                },
            ],
            /**
             * 禁止修改组件的 props
             */
            'vue/no-mutating-props': 'error',
            /**
             * 禁止出现语法错误
             */
            'vue/no-parsing-error': 'error',
            /**
             * 组件的 name 属性静止使用保留字
             */
            'vue/no-reserved-component-names': 'error',
            /**
             * 禁止覆盖保留字
             */
            'vue/no-reserved-keys': 'error',
            /**
             * 禁止在计算属性中对属性修改
             */
            'vue/no-side-effects-in-computed-properties': 'error',
            /**
             * 禁止 <template> 使用 key 属性
             */
            'vue/no-template-key': 'error',
            /**
             * 模版中的变量名禁止与前一个作用域重名
             */
            'vue/no-template-shadow': 'error',
            /**
             * 禁止使用未注册的组件
             */
            'vue/no-unregistered-components': 'off',
            /**
             * 当你的 vue 版本较老时,禁用还未支持的语法
             */
            'vue/no-unsupported-features': 'error',
            /**
             * 禁止定义在 components 中的组件未使用
             */
            'vue/no-unused-components': 'error',
            /**
             * v-for 指令的元素必须有 v-bind:key
             */
            'vue/require-v-for-key': 'error',
            /**
             * 禁止属性定义了却未使用
             */
            'vue/no-unused-properties': 'error',
            /**
             * 模版中已定义的变量必须使用
             */
            'vue/no-unused-vars': 'error',
            /**
             * 禁止在同一个元素上使用 v-if 和 v-for 指令
             */
            'vue/no-use-v-if-with-v-for': 'error',
            /**
             * props 必须用驼峰式
             */
            'vue/prop-name-casing': 'error',
            /**
             * 计算属性必须有返回值
             */
            'vue/return-in-computed-property': 'error',
            /**
             * vue 组件名称必须是多次,例如GoodDetail,不能是detail
             */
            'vue/multi-word-component-names': 0,
        },
    }
    

    1.4 stylelint

    安装依赖

    npm i -D stylelint stylelint-config-standard stylelint-less stylelint-order stylelint-webpack-plugin
    

    webpack配置

    const StylelintPlugin = require('stylelint-webpack-plugin');
    plugins: [
            new StylelintPlugin({
              files: ['**/*.{html,vue,css,less}'],
              fix: false,
              cache: true,
              failOnError: false
          })
        ]
    

    在项目根目录新建.stylelintrc.js文件,初步配置如下

    module.exports = {
      defaultSeverity: 'error',
      extends: ['stylelint-config-standard'],
      plugins: ["stylelint-order",'stylelint-less'],
      rules: {
        // 不要使用已被 autoprefixer 支持的浏览器前缀
        'media-feature-name-no-vendor-prefix': true,
        'at-rule-no-vendor-prefix': true,
        'selector-no-vendor-prefix': true,
        'property-no-vendor-prefix': true,
        'value-no-vendor-prefix': true,
        "length-zero-no-unit": true,
        // 最多允许嵌套20层,去掉默认的最多2层
        'max-nesting-depth': 20,
        // 颜色值要小写
        'color-hex-case': 'lower',
        // 颜色值能短则短
        'color-hex-length': 'short',
        // 不能用important
        'declaration-no-important': true,
      },
    };
    

    在项目的package.json中加入以下的配置

    "lint-staged": {
       "*.{html,vue,css,less}": [
         "stylelint --fix",
         "git add"
       ]
     }
    

    二、命名规范

    目前我们常用的命名方式是三种命名方式,camelCase(驼峰命名法) 、PascalCase(俗称大驼峰命名法)、kebab-case(连字符分隔命名)

    • 文件夹夹使用驼峰命名
    • 文件名组件的文件名使用大驼峰命名(PascalCase.vue),其它使用小驼峰命名(camelCase.js/ camelCase.css)
    • 图片、资源使用全小写下划线连接命名(min_jquery.js)
    • css 类名使用 中划线连字符分隔命名 (kebab-case)
    • js 中的构造函数/类 使用驼峰命名(PascalCase)
    • 方法和属性使用小驼峰命名(camelCase)
    • 枚举性质的常量使用全大写下划线分隔

    三、Git 规范

    3.1 Git 分支规范

    • 分支命名
    // 第一个标识分支类型 feature 开发 fix 修复问题 hot 线上问题修复hotfix
    // 第二个标识版本迭代时间点,比如某个里程碑时间节点
    // 第三个标识 功能点英文名
    
    feature/20220217/project_management
    
    • 分支管理
      目前我们项目都是在dev开发和维护,以后会有uat测试环境、pre预发布环境、及prod正式环境,后期我们再制定具体的发布流程,鉴于目前人员增多,单维护dev分支风险较高,如果dev分支被污染或者误操作,代码丢失的风险较大,所以建议开始维护master分支,并且dev分支指定具体的负责人来合并代码和发布,保证dev环境的稳定性,开发按某个周期迭代拉开发分支

    3.2 Git 提交规范

    约定式规范,提交的说明结构如下:

    <type>[optional scope]: <description> // <类型>[可选 范围]: <描述>
    
    [optional body] // [可选 正文]
    
    [optional footer(s)] // [可选 脚注]
    

    在项目的package.json中加入以下的配置

    "config": {
        "ghooks": {
          "pre-commit": "lint-staged",
          "commit-msg": "validate-commit-msg"
        },
        "validate-commit-msg": {
          "types": [
            "feat",
            "fix",
            "docs",
            "style",
            "refactor",
            "perf",
            "test",
            "build",
            "ci",
            "chore",
            "revert"
          ],
          "scope": {
            "required": false,
            "allowed": [
              "*"
            ],
            "validate": false,
            "multiple": false
          },
          "warnOnFail": false,
          "maxSubjectLength": 100,
          "subjectPattern": ".+",
          "subjectPatternErrorMsg": "subject does not match subject pattern!",
          "helpMessage": "",
          "autoFix": false
        },
        "commitizen": {
          "path": "./node_modules/cz-conventional-changelog"
        },
        "lint-staged": {
            "src/**/**.{js,vue}": [
                "eslint --fix",
                "git add"
            ]
        }
      },
    

    配置说明:
    我们利用ghooks ,链接git的提交过程中去触发某些事项,ghooks就是git 钩子,pre-commit就是在commit之前触发lint-staged命令,commit-msg 就是在commit的时候会去触发validate-commit-msg命令,执行validate-commit-msg之后会去校验配置项的事项,比如提交的type, 代码格式是否符合规范等信息

    关键包:

    "devDependencies": {
        "ghooks": "^2.0.4",
        "lint-staged": "^12.3.4",
        "validate-commit-msg": "^2.14.0",
        "commitizen": "^4.2.4",
        "cz-conventional-changelog": "^3.3.0",
    }
    

    项目使用:

    1. 先拉取配置最新代码
      git pull

    2. 在项目的根目录即与 .git 文件同级的目录执行npm install 下载配置依赖

    3. 切到具体的项目比如pisx-web下 执行npm install 下载配置依赖

    4. 在执行git commit 的时候有两种方式:

    方式1: 直接使用git commit 命令,说明格式安装约定规范的格式提交
    git commit -m "feat: 组件customSelect修改"
    
    方式2:使用命令交互窗口执行commit操作,使用npm run commit 或者 yarn commit 命令代替git commit 命令
    
    npm run commit 
    
    git add .
    npm run commit 
    
    **使用commitizen命令交互实现提交:**
    
    我们在项目中,如果使用commitizen命令交互的方式提交时,当要执行 git commit 的命令时,用npm run commit || yarn commit 代替 ,会调器选项命令交互
    
    通过方向键控制选择type,整个过程分为以下几步:
    
    Select the type of change that you're committing  //  选择要提交的更改类型
    
    What is the scope of this change (e.g. component or file name) // 此更改的范围是什么(例如组件或文件名,此过程非必填,可以按enter键跳过)
    
    Write a short, imperative tense description of the change (max 76 chars) //写一个简短的、命令式的变化描述(最多76个字符)
    
    Provide a longer description of the change  // 提供对更改的详细描述,非必必填,可以按enter键跳过
    
    Are there any breaking changes? (y/N) // 有什么突破性的变化吗 可以选择y/N
    
    Describe the breaking changes // 如果选择y,就需要描述这些突破性的变化
     
    Does this change affect any open issues,如果是,带上对应? (y/N)  // 这一变化是否会影响任何未决问题?(是/否),这里是描述本次修改是不是解决某个issues,如果是,带上对应issues编号
    
    **主要type:**
    
    ```javascript
     feat:新功能(feature) 
     fix:修补bug 
     docs:文档(documentation)
     style: 格式(不影响代码运行的变动) 
     refactor:重构(即不是新增功能,也不是修改bug的代码变动) 
     test:增加测试 
     chore:构建过程或辅助工具的变动 
     build:影响构建系统或外部依赖关系的更改(示例范围:gulp、Brocoli、npm) 
     ci:对CI配置文件和脚本的更改(示例范围:Travis、Circle、BrowserStack、SauceLabs) 
     chore:不修改src或测试文件的其他更改 
     revert:恢复以前的提交
    

    提交规范详解:

    1. 每个提交都必须使用类型字段前缀,它由一个名词构成,诸如 featfix , 其后接可选的范围字段,可选的 ! ,以及必要的冒号(英文半角)和空格。
    2. 当一个提交为应用或类库实现了新功能时,必须使用 feat 类型。
    3. 当一个提交为应用修复了 bug 时,必须使用 fix 类型。
    4. 范围字段可以跟随在类型字段后面。范围必须是一个描述某部分代码的名词,并用圆括号包围,例如: fix(parser):
    5. 描述字段必须直接跟在 <类型>(范围) 前缀的冒号和空格之后。 描述指的是对代码变更的简短总结,例如: fix: array parsing issue when multiple spaces were contained in string 。
    6. 在简短描述之后,可以编写较长的提交正文,为代码变更提供额外的上下文信息。正文必须起始于描述字段结束的一个空行后。
    7. 提交的正文内容自由编写,并可以使用空行分隔不同段落。
    8. 在正文结束的一个空行之后,可以编写一行或多行脚注。每行脚注都必须包含 一个令牌(token),后面紧跟 :# 作为分隔符,后面再紧跟令牌的值(受 git trailer convention 启发)。
    9. 脚注的令牌必须使用 - 作为连字符,比如 Acked-by (这样有助于 区分脚注和多行正文)。有一种例外情况就是 BREAKING CHANGE ,它可以被认为是一个令牌。
    10. 脚注的值可以包含空格和换行,值的解析过程必须直到下一个脚注的令牌/分隔符出现为止。
    11. 破坏性变更必须在提交信息中标记出来,要么在 <类型>(范围) 前缀中标记,要么作为脚注的一项。
    12. 包含在脚注中时,破坏性变更必须包含大写的文本 BREAKING CHANGE ,后面紧跟着冒号、空格,然后是描述,例如: BREAKING CHANGE: environment variables now take precedence over config files 。
    13. 包含在 <类型>(范围) 前缀时,破坏性变更必须通过把 ! 直接放在 : 前面标记出来。 如果使用了 ! ,那么脚注中可以不写 BREAKING CHANGE: , 同时提交信息的描述中应该用来描述破坏性变更。
    14. 在提交说明中,可以使用 featfix 之外的类型,比如:docs: updated ref docs. 。
    15. 工具的实现必须不区分大小写地解析构成约定式提交的信息单元,只有 BREAKING CHANGE 必须是大写的。
    16. BREAKING-CHANGE 作为脚注的令牌时必须是 BREAKING CHANGE 的同义词

    四、VUE开发规范

    4.1 组件名应该始终是多个单词的,避免跟现有的以及未来的 HTML 元素相冲突,因为所有的 HTML 元素名称都是单个单词的。

    Vue.component('todo-item', {
      // ...
    })
    

    4.2 定义prop时,必须指定其类型

    props: {
      status: {
        type: String,
        required: true,
        validator: function (value) { // 可选
          return [
            'syncing',
            'synced',
            'version-conflict',
            'error'
          ].indexOf(value) !== -1
        }
      }
    }
    

    4.3 避免把 v-if 和 v-for 同时用在同一个元素上, 使用v-for指令必须指定key属性

    <ul v-if="shouldShowUsers">
      <li
        v-for="user in users"
        :key="user.id"
      >
        {{ user.name }}
      </li>
    </ul>
    

    4.4 使用module为组件样式设置作用域

    <template>
      <button :class="[$style.button, $style.buttonClose]">X</button>
    </template>
    
    <!-- 使用 CSS Modules -->
    <style src="./helloWorld.less" lang="less" module/>
    

    4.5 只应该拥有单个活跃实例的组件应该以 The 前缀命名,以示其唯一性

    components/
    |- TheHeading.vue
    |- TheSidebar.vue
    

    4.6 和父组件紧密耦合的子组件应该以父组件名作为前缀命名

    components/
    |- SearchSidebar.vue
    |- SearchSidebarNavigation.vue
    

    4.7 在单文件组件、字符串模板和 JSX 中没有内容的组件应该是自闭合的

    <!-- 在单文件组件、字符串模板和 JSX 中 -->
    <MyComponent/>
    

    4.8 组件名应该倾向于完整单词而不是缩写

    components/
    |- StudentDashboardSettings.vue
    |- UserProfileOptions.vue
    

    4.9 在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板和 JSX 中应该始终使用 kebab-case

    props: {
      greetingText: String
    }
    
    <WelcomeMessage greeting-text="hi"/>
    

    4.10 多个 attribute 的元素应该分多行撰写,每个 attribute 一行

    <MyComponent
      foo="a"
      bar="b"
      baz="c"
    />
    

    4.11 组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法

    <!-- 在模板中 -->
    {{ normalizedFullName }}
    
    // 复杂表达式已经移入一个计算属性
    computed: {
      normalizedFullName: function () {
        return this.fullName.split(' ').map(function (word) {
          return word[0].toUpperCase() + word.slice(1)
        }).join(' ')
      }
    }
    

    4.12 把复杂计算属性分割为尽可能多的更简单的 property

    computed: {
      basePrice: function () {
        return this.manufactureCost / (1 - this.profitMargin)
      },
      discount: function () {
        return this.basePrice * (this.discountPercent || 0)
      },
      finalPrice: function () {
        return this.basePrice - this.discount
      }
    }
    

    4.13 指令缩写 (用 : 表示 v-bind:、用 @ 表示 v-on: 和用 # 表示 v-slot:)

    <input
      :value="newTodoText"
      :placeholder="newTodoInstructions"
    >
    <input
      @input="onInput"
      @focus="onFocus"
    >
    <template #header>
      <h1>Here might be a page title</h1>
    </template>
    

    4.14 组件/实例的选项的顺序

    el
    name
    parent
    functional
    delimiters
    comments
    components
    directives
    filters
    extends
    mixins
    inheritAttrs
    model
    props/propsData
    data
    computed
    watch
    beforeCreate
    created
    beforeMount
    mounted
    beforeUpdate
    updated
    activated
    deactivated
    beforeDestroy
    destroyed
    methods
    render
    renderError
    

    4.15 元素 attribute 的顺序

    is
    v-for
    v-if
    v-else-if
    v-else
    v-show
    v-cloak
    v-pre
    v-once
    id
    ref
    key
    v-model
    其它自定义
    v-on
    v-html
    v-text
    

    4.16 组件/实例选项中的空行

    props: {
      value: {
        type: String,
        required: true
      },
    
      focused: {
        type: Boolean,
        default: false
      },
    
      label: String,
      icon: String
    },
    
    computed: {
      formattedValue: function () {
        // ...
      },
    
      inputClasses: function () {
        // ...
      }
    }
    

    4.17 单文件组件的顶级元素的顺序

    <template>...</template>
    <script>/* ... */</script>
    <style>/* ... */</style>
    

    4.18 如果一组 v-if + v-else 的元素类型相同,使用 key (比如两个 <div> 元素)

    <div
      v-if="error"
      key="search-status"
    >
      错误:{{ error }}
    </div>
    <div
      v-else
      key="search-results"
    >
      {{ results }}
    </div>
    

    4.19 元素选择器避免在 scoped 中出现,在 scoped 样式中,类选择器比元素选择器更好,因为大量使用元素选择器是很慢的

    <template>
      <button class="btn btn-close">X</button>
    </template>
    
    <style scoped>
    .btn-close {
      background-color: red;
    }
    </style>
    

    4.20 优先通过 prop 和事件进行父子组件之间的通信,而不是 this.$parent 或变更 prop

    Vue.component('TodoItem', {
      props: {
        todo: {
          type: Object,
          required: true
        }
      },
      template: `
        <input
          :value="todo.text"
          @input="$emit('input', $event.target.value)"
        >
      `
    })
    

    4.21 优先通过 Vuex 管理全局状态,而不是通过 this.$root 或一个全局事件总线

    export default {
      state: {
        list: []
      },
      mutations: {
        REMOVE_TODO (state, todoId) {
          state.list = state.list.filter(todo => todo.id !== todoId)
        }
      },
      actions: {
        removeTodo ({ commit, state }, todo) {
          commit('REMOVE_TODO', todo.id)
        }
      }
    }
    
    <template>
      <span>
        {{ todo.text }}
        <button @click="removeTodo(todo)">
          X
        </button>
      </span>
    </template>
    
    <script>
    import { mapActions } from 'vuex'
    
    export default {
      props: {
        todo: {
          type: Object,
          required: true
        }
      },
      methods: mapActions(['removeTodo'])
    }
    </script>
    

    4.22 添加实例 property,以 $ 开头声明 property 变量

    Vue.prototype.$appName = 'My App'
    

    五、VUE开发文件目录

    src             源码目录
    |-- api     所有api接口
    |-- assets 静态资源,images、icons、styles等
    |-- components 公共组件
    |-- config 配置信息
    |-- constants 常量信息,项目所有Enum,全局变量等 
    |-- directives 自定义指令
    |-- filters 过滤器,全局工具
    |-- datas 模拟数据,临时存放
    |-- i18n 国际化文件
    |-- layouts 项目排版布局文件
    |-- lib 外部引用的插件存放以及修改文件
    |-- mock 模拟接口,临时存放
    |-- plugins 插件,全局使用
    |-- router 路由,统一管理
    |-- store vuex,统一管理
    |-- themes 自定义样式主题
    |-- utils 工具类方法,例如文件上传、下载方法
    |-- pages 页面目录,对应路由配置
    |   |--role role 模块名
    |   |-- |-- RoleList.vue role 列表页面
    

    相关文章

      网友评论

          本文标题:vue规范

          本文链接:https://www.haomeiwen.com/subject/jlqimrtx.html