【译】VueJS 最佳实践

原文地址: Vue.js best practices ✓ – Noteworthy - The Journal Blog
原文做者: Riccardo Polacci
译者: amandakelake

各位开发小伙伴们好!  javascript

通过一段时间对VueJs官方文档以及网上其余相关vue资源的研究,我整理了一份最佳实践和样式指南列表,方便你们写出更正确、更容易让小伙伴接受的vue代码。  html

如下有几点是一些功能/优化相关,其余是VueJs命名约定和元素排序相关。更多详细信息能够直接到最下方的总结中查看。
vue


在组件销毁时用 $off 清除事件监听

当咱们使用$on进行事件监听时,要记住在destroyed()钩子中用$off移除事件监听,能够有效防止内存泄漏。
java

使用短横线分隔的形式命名事件

触发/监听自定义事件时,应该始终使用短横线分隔。为何呢?由于不管如何最后事件名都会被自动转换为短横线分隔的形式。咱们不该该用驼峰命名或者首字母大写的形式给监听事件命名,而是使用一种更清晰有意义的方式来声明一个事件:短横线分隔git

// Emitting
this.$emit('my-event') // instead of myEvent
// Listening
v-on:my-event
复制代码

不要在created生命周期和watch中调用同一个方法

若是咱们须要在组件初始化以及侦听属性变化时调用同一个方法,一般的作法像下面这样
github

watch: {
  myProperty() {
    this.doSomething();
  }
},
created() {
  this.doSomething();
},
methods: {
  doSomething() {
     console.log('doing something...');
  }
},
复制代码

尽管上面这段代码看起来没什么问题,但created钩子里面执行的方法是多余的。咱们能够把所须要执行的方法放到watch里面,避免在created钩子里写重复代码,那将会在组件实例化的时候触发多一次。 好比像下面这样:
数组

watch: {
  myProperty: {
    immediate: true, // 该回调将会在侦听开始以后被当即调用
    handler() {
      this.doSomething();
    }
  }
},
methods: {
  doSomething() {
     console.log('doing something...');
  }
},

// 更好的方案
watch: {
  myProperty: {
    immediate: true,
    handler() {
      console.log('doing something...'); // 只用一次的方法不必在methods里面声明了
    }
  }
},
复制代码

不要忘记在 v-for 循环中使用 key 

最多见的作法是始终在模板循环中添加:key键。没有:key键的v-for循环在错误定位的时候比较麻烦,特别是动画相关
bash

使用$_做为mixins的私有属性前缀

Mixins在代码复用上是个不错的方法,它能够将重复代码组合成一个单独的模块,而后按需引入。可是(极大可能),会出现一些问题。下面,咱们重点解决属性名重复冲突的问题。框架

当咱们将mixin混入组件时,也就是将mixin内的代码与组件自身的代码进行合并,若是碰到同名属性,会发生什么?组件优先级更高,组件属性的优先级天然更高。async

若是我想让mixin代码的优先级更高,应该怎么办?咱们没法分配优先级,但能够经过正确的命名规范来避免属性重叠或者覆盖。

为了区分mixin属性和组件的属性,咱们一般使用`$_`做为属性前缀,为何呢?主要有下面几个缘由:

  1. 来自VueJs风格指南的建议 
  2. Vue 使用_前缀来定义其自身的私有属性
  3. $是Vue生态系统暴露给用户的特殊实例属性 

风格指南 — Vue.js中,他们建议像这样给mixin添加属性名称:$_myMixin_updateUser 

相对于可读性,我发现给mixin添加名称有时候也会产生一些混淆。但这也取决于mixin自己代码,特殊状况或者开发人员自己。 

经过添加一个简单的$_,就像$_updateUser同样,代码更具可读性,能够轻松分辨出组件私有属性和mixin的属性。

mixin中使用的方法或者属性应该直接在mixin中读取

mixin上一点,还有另外一点要注意的。

假设咱们建立了一个mixin,它使用了this.language属性,但这个属性并非在mixin内部定义或获取的,那么混入了这个mixin的组件就必须包含这个language属性。  

正如你已经知道的,这很是容易出错。为了提早避免错误的发生,mixin内使用到的属性或者方法最好只在mixin内部定义获取。没必要担忧重复获取属性的问题,由于VueJs在这点上很聪明,若是检测到重复读取属性,将会自动处理(大部分状况下是直接从Vuex里直接读取)。

使用首字母大写或者短横线分隔命名单文件组件

编辑器对首字母大写命名的集成度更好,对在经常使用IDE中实现自动完成/导入功能更友好。  

若是咱们想要避免文件系统大小写不敏感的问题,那么最好选择短横线分隔

给基础组件名加前缀

对于展现组件、纯组件,应该给它们加上前缀,以区别于其余的非纯组件。这能够大大提升项目可读性,提升团队协同开发体验。 

使用首字母大写命名命名JS中的组件

在JavaScript中,类和原型构造函数有默认约定使用首字母大写命名,在Vue组件中使用首字母大写命名有相同的意义。 若是咱们只经过`Vue.component`使用全局组件定义,建议使用短横线分隔命名

声明 prop 名时使用驼峰命名,但在模板中应使用短横线分隔命名

遵循每种语言的惯例:JavaScript(驼峰)和HTML(短横线分割),在JS中定义prop时用驼峰命名,在HTML中用于短横线分割命名。

遵循样式指南中的组件选项顺序

这样作可能看起来有点死板,可是在整个项目中对组件的全部选项执行相同的顺序,在查找内容和建立新组件时有很大帮助。

 VueJs样式指南能够查看这里风格指南 — Vue.js

不要在使用v-for的同一元素上使用v-if

这种作法堪称性能杀手,列表数据越大,这种作法对性能的影响越大。

用代码来看下问题吧,看如下场景:

<ul>
  <li
    v-for="game in games"
    v-if="game.isActive"
    :key="game.slug"
  >
    {{ game.title }}
  <li>
</ul>

复制代码

相似于执行下面的代码:

this.games.map(function (game) {
  if (game.isActive) {
    return game.title
  }
})
复制代码

咱们能够在这里看到,咱们将不得不迭代整个games数组,不管game.isActive是否已经改变

在像Angular这样的其余框架中,这种作法不会被编译(`* ngIf`不能进入有`* ngFor`的同一元素)


Actions必须有返回值

这跟async/await和 Vuex的 actions有关

看如下例子:

// Store
[SOME_ACTION] () {
   // 作点什么,须要一段时间才能执行完
   console.log('Action done');
}
// Consuming action
async doSomething() {
  await dispatch(SOME_ACTION);
  console.log('Do stuff now');
}
This will output:
// Do stuff now
// Action done
复制代码

发生这种状况是由于await不知道要等待什么,相反,若是咱们实际上返回了Promise.resolve(),则await将等待解析,而后再继续

// Store
[SOME_ACTION] () {
   // 作点什么,须要一段时间才能执行完
   console.log('Action done');
   Promise.resolve();
}
// Consuming action
async doSomething() {
  await dispatch(SOME_ACTION);
  console.log('Do stuff now');
}
This will output:
// Action done
// Do stuff now
复制代码

在actions和getters中使用选择器

建立选择器时,不单只是在应用逻辑中使用,还要在Vuex store中使用

直接用代码会更容易解释: 

// 假设咱们读取如下language属性
export const language = (state) => state.userConfig.language;
// 在其中一个actions中, 须要用到language:

// 很差的例子
[GET_GAMES]({ commit, rootState }) {
   const lang = rootState.userConfig.language;
   // Do stuff...
}

// 正确的例子
[GET_GAMES]({ commit, rootState }) {
   const lang = language(rootState);
   // Do stuff...
}
复制代码

总结

  1. 不要忘记在v-for循环中使用key
  2. 使用$_做为mixins的私有属性前缀
  3. mixin中使用的方法或者属性应该直接在mixin中读取
  4. 使用首字母大写或者短横线分隔命名单文件组件
  5. 给基础组件名加前缀
  6. 使用首字母大写命名命名JS中的组件
  7. 声明 prop名时使用驼峰命名,但在模板中应使用短横线分隔命名
  8. 遵循样式指南中的组件选项顺序
  9. 不要在使用v-for的同一元素上使用v-if
  10. Actions必须有返回值
  11. actionsgetters中使用选择器

来源

  • https://vuejs-tips.github.io/cheatsheet/
  • https://learn-vuejs.github.io/vue-patterns/patterns/
  • https://vuejs.org/v2/style-guide/

感谢

这篇文章是由多个在同一项目中使用VueJs的开发人员合做完成的,遵循这份样式指南和最佳实践有助于让每一个新开发人员都能尽快熟悉并上手项目代码。 

若是你有什么意见或者更好的提议,欢迎随时评论。

相关文章
相关标签/搜索