vue项目开发规范总结

2,010 阅读4分钟

强制执行的:

  • 文件名要为多个单词,且语义明确,同时要为大写驼峰

    组件名应该始终是多个单词的,根组件 App 以及 、 之类的 Vue 内置组件除外。

    反例:

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

    好例:

    export default {
      name: 'TodoItem',
      // ...
    }
    
  • 组件数据data必须为一个函数

    反例:

    export default {
      data: {
        foo: 'bar'
      }
    }
    

    好例:

    export default {
      data () {
        return {
          foo: 'bar'
        }
      }
    }
    
  • props的定义一定要详尽,例如类型、必填项、默认值、校验规则

    反例:

    props: ['status']
    

    好例:

    props: {
      status: {
        type: String,
        required: true,
        validator: function (value) {
          return [
            'syncing',
            'synced',
            'version-conflict',
            'error'
          ].indexOf(value) !== -1
        }
      }
    }
    
  • v-for设置key值

    反例:

    <ul>
      <li v-for="todo in todos">
        {{ todo.text }}
      </li>
    </ul>
    

    好例:

    <ul>
      <li
        v-for="todo in todos"
        :key="todo.id"
      >
        {{ todo.text }}
      </li>
    </ul>
    
  • 避免v-if和v-for用一起

    **永远不要把 v-if 和 v-for 同时用在同一个元素上。**当 Vue 处理指令时,v-forv-if 具有更高的优先级。

    反例:

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

    好例:

    <ul v-if="shouldShowUsers">
      <li
        v-for="user in users"
        :key="user.id"
      >
        {{ user.name }}
      </li>
    </ul>
    
  • 为组件样式设置作用域

    对于应用来说,顶级 App 组件和布局组件中的样式可以是全局的,但是其它所有组件都应该是有作用域的。

    反例:

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

    好例:

    <template>
      <button class="button button-close">X</button>
    </template>
    
    <!-- 使用 `scoped` 特性 -->
    <style scoped>
    .button {
      border: none;
      border-radius: 2px;
    }
    
    .button-close {
      background-color: red;
    }
    </style>
    
  • 使用私有属性名

    反例:

    var myGreatMixin = {
      // ...
      methods: {
        update: function () {
          // ...
        }
      }
    }
    

    好例:

    var myGreatMixin = {
      // ...
      methods: {
       	$_update: function () {
          // ...
        }
      }
    }
    

推荐执行的

  • 基础文件名

    应用特定样式和约定的基础组件 (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App 或 V

    反例:

    components/
    |- MyButton.vue
    |- VueTable.vue
    |- Icon.vue
    

    好例:

    components/
    |- BaseButton.vue
    |- AppTable.vue
    |- VIcon.vue
    
  • 单例组件名

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

    反例:

    components/
    |- Heading.vue
    |- MySidebar.vue
    

    好例:

    components/
    |- TheHeading.vue
    |- TheSidebar.vue
    
  • 自闭合组件

    在单文件组件、字符串模板和 JSX 中没有内容的组件应该是自闭合的——但在 DOM 模板里永远不要这样做。

    反例:

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

    好例:

    <!-- 在单文件组件、字符串模板和 JSX 中 -->
    <MyComponent/>
    <!-- 在 DOM 模板中 -->
    <my-component></my-component>
    
  • 模板中组件名大小写

    对于绝大多数项目来说,在单文件组件和字符串模板中组件名应该总是 PascalCase 的——但是在 DOM 模板中总是 kebab-case 的。

    反例:

    <!-- 在单文件组件和字符串模板中 -->
    <mycomponent/>
    <!-- 在单文件组件和字符串模板中 -->
    <myComponent/>
    <!-- 在 DOM 模板中 -->
    <MyComponent></MyComponent>
    

    好例:

    <!-- 在单文件组件和字符串模板中 -->
    <MyComponent/>
    <!-- 在 DOM 模板中 -->
    <my-component></my-component>
    或者
    <!-- 在所有地方 -->
    <my-component></my-component>
    
  • 模板中简单的表达式

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

    反例:

    {{
      fullName.split(' ').map(function (word) {
        return word[0].toUpperCase() + word.slice(1)
      }).join(' ')
    }}
    

    好例:

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

    应该把复杂计算属性分割为尽可能多的更简单的属性。

    反例:

    computed: {
      price: function () {
        var basePrice = this.manufactureCost / (1 - this.profitMargin)
        return (
          basePrice -
          basePrice * (this.discountPercent || 0)
        )
      }
    }
    

    好例:

    computed: {
      basePrice: function () {
        return this.manufactureCost / (1 - this.profitMargin)
      },
      discount: function () {
        return this.basePrice * (this.discountPercent || 0)
      },
      finalPrice: function () {
        return this.basePrice - this.discount
      }
    }
    
  • 带引号的特性值

    非空 HTML 特性值应该始终带引号 (单引号或双引号,选你 JS 里不用的那个)。

    反例:

    <input type=text>
    <AppSidebar :style={width:sidebarWidth+'px'}>
    

    好例:

    <input type="text">
    <AppSidebar :style="{ width: sidebarWidth + 'px' }">
    
  • 指令缩写

    指令缩写 (用 : 表示 v-bind: 、用 @ 表示 v-on: 和用 # 表示 v-slot:) 应该要么都用要么都不用。

    反例:

    <input
      v-bind:value="newTodoText"
      :placeholder="newTodoInstructions"
    >
    <input
      v-on:input="onInput"
      @focus="onFocus"
    >
    <template v-slot:header>
      <h1>Here might be a page title</h1> 
    </template>
    
    <template #footer>
      <p>Here's some contact info</p>
    </template>
    

    好例:

    <input
      :value="newTodoText"
      :placeholder="newTodoInstructions"
    >
    <input
      v-bind:value="newTodoText"
      v-bind:placeholder="newTodoInstructions"
    >
    <input
      @input="onInput"
      @focus="onFocus"
    >
    <input
      v-on:input="onInput"
      v-on:focus="onFocus"
    >