vue 官方风格指南解析

更新日期: 2020-01-28阅读: 1.9k标签: 指南
vue 有个官方的风格指南,我从中摘抄了些认为比较重要、自己常忽略的点,加上一些分析列出来。也可以直接去观看风格指南:https://cn.vuejs.org/v2/style


单文件组件文件的命名

文件名要么是单词开头大写,要么是横线连接

MyComponent.vue 或 my-component.vue


为组件样式设置作用域

除了根组件或者布局组件,都要加上 scoped 设置作用域,避免影响其它地方的样式


永远不要把 v-if 和 v-for 同时用在同一个元素上

  • 如果要过滤列表,使其隐藏不符合条件的项目,可以使用计算属性,预先筛选出符合条件的数组
v-for="user in users" v-if="user.isActive"
/** 要换成 **/
v-for="user in activeUsers"
computed () {
    return this.users.filter((item) => {
        return item.isActive
    })
}

好处:

*   过滤后的列表_只_会在`users`数组发生相关变化时才被重新运算,过滤更高效。
*   使用`v-for="user in activeUsers"`之后,我们在渲染的时候只遍历活跃用户,渲染更高效。
*   解耦渲染层的逻辑,可维护性 (对逻辑的更改和扩展) 更强。
  • 如果希望控制列表显示,将 v-if 移到外层容器元素上
 v-for="user in users" v-if="shouldShowUsers"
 /** 要换成 **/
 <ul v-if="shouldShowUsers">
     <li v-for="user in users"></li>
 </ul>
 
 好处:
 
 *   如上
 *   通过将 v-if 移动到容器元素,我们不会再对列表中的每个用户检查 shouldShowUsers。取而代之的是,我们只检查它一次,且不会在 shouldShowUsers 为否的时候运算 v-for。


Prop 定义

prop 尽量详细,不使用数组方式,而是用对象列出更多选项,至少需要指定其类型。

好处:

  • 它们写明了组件的 api,所以很容易看懂组件的用法;
  • 在开发环境下,如果向一个组件提供格式不正确的 prop,Vue 将会告警,以帮助你捕获潜在的错误来源。


Prop 名格式

prop 应当使用 驼峰命名法,而在模板和 JSX 中使用时,要用横线连接(html 的约定)

正确例子:

<WelcomeMessage greeting-text="hi"/>

props: {
  greetingText: String
}


组件名为多个单词

组件名始终应该是多个单词,避免和将来的 HTML 元素相冲突,例如

export default {
    // name: 'Todo',不推荐
    name: 'TodoItem'
}


基础组件名

对于不包含全局状态的(比如 vuex store)、展示类的、无逻辑或无状态的基础组件,例如 table、button、icon 等,应该都以一个特定的前缀开头,统一风格且与其他功能组件区分开来

反例:

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


正确例子:

components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue

components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue

components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue


单例组件名

对于每个页面只使用一次、不接受任何 prop (即内容写死了)的组件(例如顶部的公司 logo、底部的版权声明),要以 The 前缀命名,以示其唯一性

反例:

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

正确例子:

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


紧密耦合的组件名

对于和父组件紧密耦合的子组件(即只在指定的父组件里用到的),命名方式应该规范统一:父组件名+本身名字,因为编辑器通常会按字母顺序组织文件,所以这样做可以把相关联的文件排在一起。

注意:这里的父组件也是自定义组件,例如自定义列表组件,其还有只在其本身使用的自定义列表 item 子组件、自定义按钮子组件,子组件命名要规范

现在通常做法(components 的父组件使用文件夹形式,包含 index.vue 和子组件文件夹):

components/
|- TodoList/
   |- Item/
      |- index.vue
      |- Button.vue
   |- index.vue

或者单纯是命名上相似:

components/
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue

正确例子:

components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue

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


自闭合组件

对于没有内容的组件,在允许的情况下要使用自闭合形式,以提醒使用者它们不仅没有内容,而且是刻意没有内容,且代码也更简洁。

允许的情况:单文件组件、字符串模板、JSX

不允许的情况:dom 模板(一些 HTML 元素中,例如 <ul>、<ol>、<table> 和 <select>,因为 HTML 不支持自闭合的自定义元素)

反例:

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

<!-- 在 DOM 模板中 -->
<my-component/>

正确例子:

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

<!-- 在 DOM 模板中 -->
<my-component></my-component>


模板中的组件名格式

模板中组件名的书写方式,和文件的命名方式一样,要么是单词开头大写,要么是横线连接,两者不应该混用

还要注意,在 DOM 模板中,不支持单词大小写方式,因为 HTML 是大小写不敏感的

正确例子:

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

或者:

<!-- 在所有地方 -->
<my-component></my-component>


完整单词的组件名

组件名应该用完整的单词,而不是缩写。不要为了减少名字的长度而用缩写(尤其是不常用的缩写),现在编辑器的自动补全功能已经让写长命名的代价非常低,而完整的命名带来的明确理解性是非常宝贵的。

反例:

components/
|- SdSettings.vue
|- UProfOpts.vue

正确例子:

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


多个 attribute 的元素

元素的多个 attribute 应该分多行,每个 attribute 一行,更易读

反例:

<img src="https://vuejs.org/images/logo.png" alt="Vue Logo">

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

正确例子:

<img
  src="https://vuejs.org/images/logo.png"
  alt="Vue Logo"
>

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


模板中简单的表达式

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

反例:

{{
  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
  }
}


指令缩写

用 : 表示 v-bind:、用 @ 表示 v-on: 和用 # 表示 v-slot:,应该要么都用要么都不用。


scoped 中的元素选择器

在 scoped 的 scss/less/css 中,避免出现元素选择器,要使用 class 类选择器。

原因:

为了给样式设置作用域,Vue 会为元素添加一个独一无二的 attribute,例如>问题在于大量的元素和 attribute 组合的选择器 (比如 button[>反例: <template> <button>X</button> </template> <style scoped> button { background-color: red; } </style> 正确例子: <template> <button>X</button> </template> <style scoped> .btn-close { background-color: red; } </style>


隐性的父子组件通信

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


在 v-if/v-else-if/v-else 中使用 key

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

默认情况下,Vue 会尽可能高效的更新 DOM。这意味着其在相同类型的元素之间切换时,会修补已存在的元素,而不是将旧的元素移除然后在同一位置添加一个新元素。如果本不相同的元素被识别为相同,则会出现意料之外的结果。

如下代码,在按钮点击切换时,不会触发 transition 效果,因为它是在本来的 button 上进行修改,没有进行移除新增操作。在这里查看效果

反例:

<transition>
    <button v-if="isEditing" v-on:click="isEditing = false">
      Save
    </button>
    <button v-else v-on:click="isEditing = true">
      Edit
    </button>
</transition>

<style>
  .v-enter-active,
  .v-leave-active {
    transition: all 1s;
  }
  .v-enter,
  .v-leave-to {
    opacity: 0;
    transform: translateY(30px);
  }
  .v-leave-active {
    position: absolute;
  }
</style>

解决方法:

正确例子:

<transition>
    <button v-if="isEditing" v-on:click="isEditing = false" key="save">
      Save
    </button>
    <button v-else v-on:click="isEditing = true" key="edit">
      Edit
    </button>
</transition>

链接: https://www.fly63.com/article/detial/8774

Node.js 指南(迁移到安全的Buffer构造函数)

由于安全性和可用性问题,不建议使用 Buffer()和 new Buffer()构造函数,请改用 new Buffer.alloc()、Buffer.allocUnsafe()或 Buffer.from()构造方法。

JS对象的 rest/spread 属性指南

在ES5中,咱们合并对象通常使用Lodash的_.extend(target, [sources]) 方法,在ES6中咱们使用 Object.assign(target, [sources])来合并对象,当然现在最常用应该是使用 Rest/Spread(展开运算符与剩余操作符)。

Web 堆栈选择指南:JAMStack vs MEAN vs LAMP

开发人员需要做的决策有很多。当 Web 应用程序的需求确定下来之后,就该选择效率最高的 Web 技术栈了。Web 技术栈是用于创建 Web 应用程序的技术工具集。一套 Web 技术栈由 OS(操作系统)、Web 服务器

Js闭包使用姿势指南

闭包就是指 能够访问另一个函数作用域的变量的函数 ,闭包就是一个函数,能够访问其他函数的作用域中的变量,js有一个全局对象,在浏览器下是window,node下是global,所有的函数都在这个对象下

使用JavaScript进行面向对象编程的指南

一切都从对象开始。对象,即我们相互交流的一个载体,有其属性和方法。对象是面向对象编程的核心,不仅用于JavaScript,而且还适用于Java、C语言、C++等。

AssemblyScript 入门指南

WebAssembly(Wasm)是 Web 浏览器中相对较新的功能,但它地扩展了把 Web 作为服务应用平台的功能潜力。对于 Web 开发人员来说,学习使用 WebAssembly 可能会有一个艰难的过程

程序员聊天指南,建议先码后看

很多接触过程序员的人,都有一种体会:程序员=聊天终结者。经常用简短有力的几个字结束掉你苦心经营的聊天氛围,比如:你现在忙不忙?忙。那我真的是打扰了

SVG入门指南

SVG,即可缩放矢量图形(Scalable Vector Graphics),是一种 XML 应用,可以以一种简洁、可移植的形式表示图形信息。目前,人们对 SVG 越来越感兴趣。大多数现代浏览器都能显示 SVG 图形,并且大多数矢量绘图软件都能导出 SVG 图形

JavaScript 类完整指南

JavaScript 使用原型继承:每个对象都从其原型对象继承属性和方法。在 JavaScript 中不存在 Java 或 Swift 等语言中所使用的作为创建对象 蓝图的传统类,原型继承仅处理对象。

Quill 实践指南

很多时候 <textarea> 并不能满足我们对文本输入的需求,当我们需要为输入的文本添加格式时,我们需要使用像 quill 这样的富文本编辑器来完成富文本的输入。本文将会详细的讲解如何使用 quill 定制一个自己的富文本编辑器。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!