[译] VueJs 最佳实践✓

原文连接javascript

开发者们,大家好。html

通过网上的一段搜索以及查阅Vue.js的文档,我写下了本文中关于Vue的最佳实践以及风格指南,从而能够更正确,更优雅的使用Vue.js。vue

下面的要点指出了其中一些功能/优化相关,其余是VueJs命名约定和元素排序。 更详细的信息能够在连接中找到。java

题图

在组件销毁以后使用$off清除事件监听器

当咱们在使用$on监听事件的时候,老是须要在事件销毁(destroyed())的时候使用$off清除事件监听,这样能够有效防止内存泄漏。git

事件名称使用短横线式命名(kebab-case)

在派发/监听事件的时候,咱们应该始终使用短横线式命名(kebab-case),这是由于事件最终会被自动转换为该命名方式。咱们监听的时间格式不能是驼峰式以及Pascal式,所以在声明时间的时候,最好就讲时间命名为短横线式。例如:github

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

避免在created以及watch中调用相同的method

若是咱们须要触发组件初始化和属性更改的方法,一般的作法是执行如下操做:api

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

尽管这样看起来挺正确的,可是这里对于created()的使用是多余的。咱们本能够将全部的功能放入watch,从而避免在created()里面写重复的代码,这样一样能够在生成组件实例的时候触发。例如:浏览器

watch: {
  myProperty: {
    immediate: true, // forcing handler on initial status
    handler() {
      this.doSomething();
    }
  }
},
methods: {
  doSomething() {
     console.log('doing something...');
  }
},
// Even better solution
watch: {
  myProperty: {
    immediate: true, // forcing handler on initial status
    handler() {
      console.log('doing something...'); // No need to declare a function on methods for 1 use case
    }
  }
},
复制代码

老是在v-for循环中使用 :key

一般来讲,在模板的循环中添加:key是一个最佳实践,不包含:keyv-for循环会致使很难以查出的bug,尤为是在动画效果里面。app

为混入属性(mixins properties)使用$_符号标记

Mixins 是是将重复代码放入一个块并将其导入屡次的好方法,但不少状况下,这可能会致使一些问题。 在这一点上,咱们将解决重叠属性的问题。框架

当咱们讲一个mixin导入到咱们的组件当中时,其实是在吧minxin的代码和组件中本来的代码合并(merge)起来,那么同名的属性会呈现什么样呢?通常来讲,组件的优先级更高,而且会覆盖mixin。

那么我要是须要mixin有更高的优先级,该怎么办呢?开发过程当中并不能声明优先级,可是你能够避免属性的叠加,而且使用合适的命名方式来规避属性的重写。

In order to differentiate mixin properties from Component properties we use $_. Why these symbols? Well, several reasons: 为了将Mixin的属性与组件的属性相区分,咱们使用$_,缘由以下:

  1. 这是Vuejs传统风格
  2. _在Vuejs中表示私有属性
  3. $属于Vue的保留字

风格指南能够看到官方推荐的Mixin命名:$_myMixin_updateUser

我发现添加mixin名称会产生比可读性更多的混乱。 但这也取决于mixin,状况和开发人员。

经过在Mixin以前添加$_,例如$_updateUser,我发现代码更具可读性,能够轻松区分Component和Mixin。

在Mixin中使用的属性必须所有包含在Mixin之中

继上一点以后,mixins还有另一个问题:mixin不够独立。

若是咱们建立一个使用的mixin,比方说,this.language并无从mixin中的store中定义或获取此属性,那么定义mixin的Component必须包含language属性。

正如您已经知道的那样,这很是容易出错。 为了不这些错误,咱们在mixin里面获取全部须要的数据。 不要担忧,若是咱们两次获取数据,VueJs是聪明的,若是检测到从store获取到相同的东西,将不会作双重工做(由于大多数状况下会从Vuex获取数据)

对单文件组件使用PascalCase或kebab-case

PascalCase与编辑器具备更好的集成,并容许在经常使用IDE中实现更好的自动完成/导入功能。

若是咱们想要避免使用不区分大小写的文件系统的问题,那么就应该使用kebab-case。

基础组件名称以前加前缀

装饰性、基础组件应该有一个前缀,以区别于其余复杂组件。 这大大提升了项目的可读性以及团队和开发人员之间的合做效率。

JS组件需以PascalCase 命名

在JavaScript中,类和原型构造方法通常使用PascalCase 命名,而且Vue组件也须要按此方式命名。

若是咱们只经过Vue.component使用全局组件,那可使用kebab-case。

Prop 在声明时须要按照CamelCase命名,可是在模板中须要改为kebab-case

HTML 中的特性名是大小写不敏感的,因此浏览器会把全部大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名须要使用其等价的 kebab-case (短横线分隔命名) 命名。

按照风格指南设置组件内部选项顺序

这看起来没什么意义,可是按此规则写成的组件更适合于大型多人开发项目,而且方便往后的扩展。

详情在[风格指南]vuejs.org/v2/style-gu…)

不在同一个元素上同时使用v-if和v-for

这是一个性能杀手,列表越长,这种不良作法会带来越多的性能损失。

让咱们用代码解释一下,想象一下如下案例场景:

<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是否改变其活动状态,咱们每一次都须要遍历整个games列表。

在Angular等其余框架中,这样写不能经过编译:

(**ngIf* can't go in the same element where there is an **ngFor*)*。

Actions必需要有返回值

这是Vuex的actions和async/await的冲突形成的,请看这个例子:

// Store
[SOME_ACTION] () {
   // Doing stuff that takes a while
   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] () {
   // Doing stuff that takes a while
   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内部使用选择器

咱们建立选择器是不只要在app过程当中使用,还要在Vuex的store中使用。

例如:

// We have this selector
export const language = (state) => state.userConfig.language;
// In one of our actions, we need language:
// Bad
[GET_GAMES]({ commit, rootState }) {
   const lang = rootState.userConfig.language;
   // Do stuff...
}
// Good
[GET_GAMES]({ commit, rootState }) {
   const lang = language(rootState);
   // Do stuff...
}
复制代码

总结

  1. 在组件销毁以后使用$off清除事件监听器 source
  2. 事件名称使用短横线式命名(kebab-case) source
  3. 避免在created以及watch中调用相同的method source
  4. **老是在v-for循环中使用 :keysource
  5. 为混入属性(mixins properties)使用$_符号标记 source
  6. 在Mixin中使用的属性必须所有包含在Mixin之中
  7. 对单文件组件使用PascalCase或kebab-case source
  8. 基础组件名称以前加前缀 source
  9. JS组件需以PascalCase 命名 source
  10. **Prop 在声明时须要按照CamelCase命名,可是在模板中须要改为kebab-casesource
  11. 按照风格指南设置组件内部选项顺序 source
  12. 不在同一个元素上同时使用v-if和v-for source
  13. Actions必需要有返回值
  14. 在actions和getters内部使用选择器

参考文献

后记

这篇文章是在使用VueJs以后完成的。 遵循这些风格指南和最佳实践有助于让每一个新开发者都有宾至如归的感受,并当即投入到工做中!

翻译后记

这篇文章着重于代码风格,良好的代码风格是优秀代码的必要条件,也是多人合做过程当中必不可少的一部分,以前阅读过阿里的Java手册,深感一个庞大的项目,除了语法以外,也必须在开发以前对于全体开发者的代码风格进行约束,虽然目前有了Eslint之类的风格检查工具,可是诸如命名等仍是须要统一约束。

文章还对一些会影响性能以及容易报错的写法进行了纠正。整体来讲值得一读,也值得翻译过来给你们看看😉

相关文章
相关标签/搜索