zoukankan      html  css  js  c++  java
  • Vue风格指南总结

    Vue风格指南是官方推荐的代码规范,按照指南开发大型Vue应用,可以避免项目后期出现不可预料的问题或BUG。

    官方把规范定义了四个级别:A级表示必要的,B级表示强烈推荐,C级表示推荐,D级表示谨慎使用。示例代码官方给了正例和反例,我只总结了正例的写法。就像开发API一样,正确的情况通常只有一种,而错误的情况会有很多种,所以只要记住正确的就行了

    A级 必要的

    自定义组件在命名时,应该使用多个单词,这样可以避免未来和HTML元素冲突

    Vue.component('todo-item', {
      // ...
    })
    export default {
      name: 'TodoItem',
      // ...
    }
    

    组件中的data必须是一个函数,这样可以保证组件在复用时,每个组件实例都能管理自己的数据,避免数据的交叉感染

    Vue.component('some-comp', {
      data: function () {
        return {
          foo: 'bar'
        }
      }
    })
    
    export default {
      data () {
        return {
          foo: 'bar'
        }
      }
    }
    
    // 在Vue根实例上可以直接使用对象,因为只存在一个这样的实例
    new Vue({
      data: {
        foo: 'bar'
      }
    })
    

    定义Prop应该尽量详细,至少需要指定其类型,这样能更容易的看懂组件的用法

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

    在组件上使用v-for必须和key配合,这样可以在更新 DOM 的时候,Vue 将会优化渲染,把可能的 DOM 变动降到最低

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

    永远不要把 v-if 和 v-for 同时用在同一个元素上,因为这样做会导致每次条件判断,都需要重新遍历整个列表。可以把条件判断放到容器上

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

    组件的样式必须设置作用域,设置作用域的方式可以是使用scoped属性、CSS Modules或者基于 class 的类似 BEM 的策略

    基于class的作用域策略是更值得推荐的,因为这样外部更容易覆写组件样式

    <template>
      <button class="button button-close">X</button>
    </template>
    
    <!-- 使用 `scoped` 特性 -->
    <style scoped>
    .button {
      border: none;
      border-radius: 2px;
    }
    
    .button-close {
      background-color: red;
    }
    </style>
    
    <template>
      <button :class="[$style.button, $style.buttonClose]">X</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">X</button>
    </template>
    
    <!-- 使用 BEM 约定 -->
    <style>
    .c-Button {
      border: none;
      border-radius: 2px;
    }
    
    .c-Button--close {
      background-color: red;
    }
    </style>
    

    在插件、混入等扩展中始终为自定义的私有属性使用 $_ 前缀,并附带一个命名空间以回避和其它作者的冲突 (比如 $yourPluginName)。

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

    B级 推荐

    单文件组件的文件名应该要么始终是单词大写开头 (PascalCase),要么始终是横线连接 (kebab-case)。

    components/
    |- MyComponent.vue
    components/
    |- my-component.vue
    

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

    components/
    |- BaseButton.vue
    |- BaseTable.vue
    |- BaseIcon.vue
    
    components/
    |- AppButton.vue
    |- AppTable.vue
    |- AppIcon.vue
    
    components/
    |- VButton.vue
    |- VTable.vue
    |- VIcon.vue
    

    单例组件应该以 The 前缀命名,以示其唯一性

    单例组件不是指只能用于一个单页面,而是指每个页面只使用一次,并且这些组件永远不接受任何 prop,因为它们是为你的应用定制的,而不是它们在你的应用中的上下文

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

    和父组件紧密耦合的子组件应该以父组件名作为前缀命名,因为编辑器通常会按字母顺序组织文件,这样做可以把相关联的文件排在一起

    components/
    |- SearchButtonClear.vue
    |- SearchButtonRun.vue
    |- SearchInputQuery.vue
    |- SearchInputExcludeGlob.vue
    |- SettingsCheckboxTerms.vue
    |- SettingsCheckboxLaunchOnStartup.vue
    

    在单文件组件、字符串模板和 JSX 中没有内容的组件应该是自闭合的,但在 DOM 模板里永远不要这样做,因为HTML 并不支持自闭合的自定义元素

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

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

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

    JS/JSX 中的组件名应该始终是 PascalCase 的,尽管在较为简单的应用中使用 Vue.component 进行全局组件注册时,可以使用 kebab-case 字符串

    Vue.component('MyComponent', {
      // ...
    })
    Vue.component('my-component', {
      // ...
    })
    
    import MyComponent from './MyComponent.vue'
    export default {
      name: 'MyComponent',
      // ...
    }
    

    多个特性的元素应该分多行撰写,每个特性一行,因为这样更易读

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

    C级 推荐

    单文件组件应该总是让 <script><template><style> 标签的顺序保持一致。且<style> 要放在最后,因为另外两个标签至少要有一个。

    <!-- ComponentA.vue -->
    <template>...</template>
    <script>/* ... */</script>
    <style>/* ... */</style>
    
    <!-- ComponentB.vue -->
    <template>...</template>
    <script>/* ... */</script>
    <style>/* ... */</style>
    
    <!-- ComponentA.vue -->
    <script>/* ... */</script>
    <template>...</template>
    <style>/* ... */</style>
    
    <!-- ComponentB.vue -->
    <script>/* ... */</script>
    <template>...</template>
    <style>/* ... */</style>
    

    D级 谨慎使用

    官方把D级定义为谨慎使用,表示的是这样做可能有潜在的危险,我下面直接把推荐的做法总结了一下

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

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

    隐性的父子组件通信

    应该优先通过 prop 和事件进行父子组件之间的通信,而不是使用 this.\(parent 改变 prop。尽管this.\)parent 这种做法在很多简单的场景下可能会更方便,但这样做会牺牲数据流向的简洁性

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

    官方文档

    优秀文章首发于聚享小站,欢迎关注!
  • 相关阅读:
    openlayers + webpack
    openlayers Map 和 es6的容器Map重名
    git 代理
    剑魂史诗套配装
    剑魂卢克攻略
    DNF斩铁剑魂每日1-5及打团须知
    APP自识别安卓苹果
    各浏览器老板键
    Apache+mod_encoding解决URL中文编码问题
    linux命令之crontab定时执行任务
  • 原文地址:https://www.cnblogs.com/yesyes/p/15356916.html
Copyright © 2011-2022 走看看