• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 优先级 A 的规则:必要的 (规避错误)

    这些规则有助于防止错误,因此不惜一切代价学习并遵守它们。例外情况可能存在,但应该非常罕见,并且只能由具有 JavaScript 和 Vue 专业知识的人员制作。

    组件名为多个单词

    组件名应该始终由多个单词组成,除了根组件App,以及<transition><component>之类的 Vue 内置组件。

    这样做可以避免与现有以及未来的 HTML 元素产生冲突,因为所有的 HTML 元素名称都是单个单词的。

    反面例子

    <!-- in pre-compiled templates -->
    <Item />
    
    <!-- in in-DOM templates -->
    <item></item>
    

    正面例子

    <!-- in pre-compiled templates -->
    <TodoItem />
    
    <!-- in in-DOM templates -->
    <todo-item></todo-item>
    


    Prop 定义应尽量详细

    在提交的代码中,prop 的定义应该尽量详细,至少指定其类型。

    反面例子

    // This is only OK when prototyping
    props: ['status']
    

    正面例子

    props: {
      status: String
    }
    // Even better!
    props: {
      status: {
        type: String,
        required: true,
    
        validator: value => {
          return [
            'syncing',
            'synced',
            'version-conflict',
            'error'
          ].includes(value)
        }
      }
    }
    


    为 v-for 设置 key 值

    始终以key配合v-for。在组件上必须始终以 key 配合 v-for,以便维护内部组件及其子树的状态。即使对于元素,维持可预测的行为也是一种好的做法。例如动画中的对象固化(object constancy)。

    反面例子

    <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。一般我们在两种常见的情况下会倾向于这样做:

    • 为了对列表中的项目进行过滤(比如v-for="user in users" v-if="user.isActive")。在这种情形下,请将 users 替换为一个计算属性(比如 activeUsers),返回过滤后的列表。
    • 为了避免渲染本应该被隐藏的列表(比如v-for="user in users" v-if="shouldShowUsers")。这种情形下,请将 v-if 移动至容器元素上(比如 ul、ol)。

    反面例子

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

    正面例子

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


    为组件样式设置作用域

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

    这条规则只适用于单文件组件。你不一定要使用scoped attribute。作用域也可以通过 CSS Modules(一个基于 class 的,类似 BEM 的策略)或者其它的库/约定来实现。

    不管怎样,对于组件库来说,我们应该更倾向于选用基于 class 的策略,而不是scoped attribute。

    这会让覆写内部样式变得更容易:使用人类可理解的 class 名称,没有太高的选择器优先级,而且不太会导致冲突。

    反面例子

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

    正面例子

    <template>
      <button class="button button-close">×</button>
    </template>
    
    <!-- 使用 `scoped` attribute -->
    <style scoped>
    .button {
      border: none;
      border-radius: 2px;
    }
    
    .button-close {
      background-color: red;
    }
    </style>
    
    <template>
      <button :class="[$style.button, $style.buttonClose]">×</button>
    </template>
    
    <!-- 使用 CSS modules -->
    <style module>
    .button {
      border: none;
      border-radius: 2px;
    }
    
    .buttonClose {
      background-color: red;
    }
    </style>
    
    <template>
      <button class="c-Button c-Button--close">×</button>
    </template>
    
    <!-- 使用 BEM 约定 -->
    <style>
    .c-Button {
      border: none;
      border-radius: 2px;
    }
    
    .c-Button--close {
      background-color: red;
    }
    </style>
    


    私有 property 名称必要

    使用模块作用域来确保外部无法访问到私有函数。如果无法做到这一点,就始终应该为插件、mixin 等不考虑对外公开 API 的自定义私有 property 使用$_前缀。并附带一个命名空间,以回避和其它作者的冲突(比如$_yourPluginName_)。

    反面例子

    const myGreatMixin = {
      // ...
      methods: {
        update() {
          // ...
        }
      }
    }
    
    const myGreatMixin = {
      // ...
      methods: {
        _update() {
          // ...
        }
      }
    }
    
    const myGreatMixin = {
      // ...
      methods: {
        $update() {
          // ...
        }
      }
    }
    
    const myGreatMixin = {
      // ...
      methods: {
        $_update() {
          // ...
        }
      }
    }
    

    正面例子

    const myGreatMixin = {
      // ...
      methods: {
        $_myGreatMixin_update() {
          // ...
        }
      }
    }
    
    // Even better!
    const myGreatMixin = {
      // ...
      methods: {
        publicMethod() {
          // ...
          myPrivateFunction()
        }
      }
    }
    
    function myPrivateFunction() {
      // ...
    }
    
    export default myGreatMixin