Vue 开发规范(中)

3,874 阅读5分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文同时参与 「掘力星计划」  ,赢取创作大礼包,挑战创作激励金

本文上下两篇链接 《Vue 开发规范(上)》 《 Vue 开发规范(下)》 连载阅读体验更佳。

将 this 赋值给 component 变量

在 Vue.js 组件上下文中,this指向了组件实例。因此当你切换到了不同的上下文时,要确保 this 指向一个可用的 component 变量。

换句话说,如果你正在使用 ES6 的话,就不要再编写 var self = this; 这样的代码了,您可以安全地使用 Vue 组件。

为什么?

  • 使用 ES6,就不再需要将 this 保存到一个变量中了。
  • 一般来说,当你使用箭头函数时,会保留 this 的作用域。(译者注:箭头函数没有它自己的 this 值,箭头函数内的 this 值继承自外围作用域。)
  • 如果你没有使用 ES6,当然也就不会使用 箭头函数 啦,那你必须将 “this” 保存到到某个变量中。这是唯一的例外。

怎么做?

<script type="text/javascript"> 
export default { methods: { hello() { return 'hello'; }, printHello() { console.log(this.hello()); }, }, }; 
</script>
<!-- 避免 -->
<script type="text/javascript"> 
export default { methods: { hello() { return 'hello'; }, printHello() { const self = this; // 没有必要 console.log(self.hello()); }, }, }; 
</script>

组件结构化

按照一定的结构组织,使得组件便于理解。

为什么?

  • 导出一个清晰、组织有序的组件,使得代码易于阅读和理解。同时也便于标准化。
  • 按首字母排序 properties、data、computed、watches 和 methods 使得这些对象内的属性便于查找。
  • 合理组织,使得组件易于阅读。(name; extends; props, data 和 computed; components; watch 和 methods; lifecycle methods 等)。
  • 使用 name 属性。借助于 vue devtools 可以让你更方便的测试。
  • 合理的 CSS 结构,如 BEM 或 rscss - 详情?。
  • 使用单文件 .vue 文件格式来组件代码。

怎么做?

组件结构化

<template lang="html">
  <div class="Ranger__Wrapper">
    <!-- ... -->
  </div>
</template>
<script type="text/javascript"> 
export default { 
// 不要忘记了 name 属性 name: 'RangeSlider', 
// 组合其它组件 extends: {}, 
// 组件属性、变量 props: { bar: {}, 
// 按字母顺序 foo: {}, fooBar: {}, }, 
// 变量 data() {}, computed: {}, 
// 使用其它组件 components: {}, 
// 方法 watch: {}, methods: {}, 
// 生命周期函数 beforeCreate() {}, mounted() {}, }; 
</script>

<style scoped> .Ranger__Wrapper { /* ... */ } </style>

组件事件命名

Vue.js 提供的处理函数和表达式都是绑定在 ViewModel 上的,组件的每一个事件都应该按照一个好的命名规范来,这样可以避免不少的开发问题,具体可见如下 为什么。

为什么?

  • 开发者可以随意给事件命名,即使是原生事件的名字,这样会带来迷惑性。
  • 过于宽松的事件命名可能与 DOM 模板不兼容。

怎么做?

  • 事件名也使用连字符命名。
  • 一个事件的名字对应组件外的一组意义操作,如:upload-success、upload-error 以及 dropzone-upload-success、dropzone-upload-error (如果需要前缀的话)。
  • 事件命名应该以动词(如 client-api-load) 或是 形容词(如 drive-upload-success)结尾。(出处)

避免 this.$parent

Vue.js 支持组件嵌套,并且子组件可访问父组件的上下文。访问组件之外的上下文违反了基于模块开发的第一原则。因此你应该尽量避免使用 this.$parent。

为什么?

  • 组件必须相互保持独立,Vue 组件也是。如果组件需要访问其父层的上下文就违反了该原则。
  • 如果一个组件需要访问其父组件的上下文,那么该组件将不能在其它上下文中复用。

怎么做?

  • 通过 props 将值传递给子组件。
  • 通过 props 传递回调函数给子组件来达到调用父组件方法的目的。
  • 通过在子组件触发事件来通知父组件。

谨慎使用 this.$refs

Vue.js 支持通过 ref 属性来访问其它组件和 HTML 元素。并通过 this.$refs 可以得到组件或 HTML 元素的上下文。在大多数情况下,通过 this.$refs来访问其它组件的上下文是可以避免的。在使用的的时候你需要注意避免调用了不恰当的组件 API,所以应该尽量避免使用 this.$refs

为什么?

  • 组件必须是保持独立的,如果一个组件的 API 不能够提供所需的功能,那么这个组件在设计、实现上是有问题的。
  • 组件的属性和事件必须足够的给大多数的组件使用。

怎么做?

  • 提供良好的组件 API
  • 总是关注于组件本身的目的。
  • 拒绝定制代码。如果你在一个通用的组件内部编写特定需求的代码,那么代表这个组件的 API 不够通用,或者你可能需要一个新的组件来应对该需求。
  • 检查所有的 props 是否有缺失的,如果有提一个 issue 或是完善这个组件。
  • 检查所有的事件。子组件向父组件通信一般是通过事件来实现的,但是大多数的开发者更多的关注于 props 从忽视了这点。
  • Props向下传递,事件向上传递!。以此为目标升级你的组件,提供良好的 API 和 独立性。
  • 当遇到 propsevents 难以实现的功能时,通过 this.$refs来实现。
  • 当需要操作 DOM 无法通过指令来做的时候可使用 this.$ref 而不是 JQuery、document.getElement*、document.queryElement
  • 基础使用准则是,能不用ParseError: KaTeX parse error: Expected 'EOF', got '就' at position 5: refs就̲尽量不用,如果用,尽量不要通过refs操作状态,可以通过$refs调用methods
<!-- 推荐,并未使用 this.$refs -->
<range :max="max" :min="min" @current-value="currentValue" :step="1"></range>

<!-- 使用 this.$refs 的适用情况-->
<modal ref="basicModal">
  <h4>Basic Modal</h4>
  <button class="primary" @click="$refs.basicModal.hide()">Close</button>
</modal>
<button @click="$refs.basicModal.open()">Open modal</button>

<!-- Modal component -->
<template>
  <div v-show="active">
    <!-- ... -->
  </div>
</template>
<script> 
export default { // ... data() { return { active: false, }; }, methods: { open() { this.active = true; }, hide() { this.active = false; }, }, // ... }; 
</script>
<!-- 这里是应该避免的 -->
<!-- 如果可通过 emited 来做则避免通过 this.$refs 直接访问 -->
<template>
  <range :max="max" :min="min" ref="range" :step="1"></range>
</template>

<script> 
export default { // ... methods: { getRangeCurrentValue() { return this.$refs.range.currentValue; }, }, // ... }; 
</script>

使用组件名作为样式作用域空间

Vue.js 的组件是自定义元素,这非常适合用来作为样式的根作用域空间。可以将组件名作为 CSS 类的命名空间。

为什么?

  • 给样式加上作用域空间可以避免组件样式影响外部的样式。
  • 保持模块名、目录名、样式根作用域名一样,可以很好的将其关联起来,便于开发者理解。

怎么做?

使用组件名作为样式命名的前缀,可基于 BEM 或 OOCSS 范式。同时给 style 标签加上 scoped 属性。加上 scoped 属性编译后会给组件的 class 自动加上唯一的前缀从而避免样式的冲突。

<style scoped> /* 推荐 */ 
.MyExample { } 
.MyExample li { } 
.MyExample__item { } 
/* 避免 */ 
.My-Example { } 
/* 没有用组件名或模块名限制作用域, 不符合 BEM 规范 */ 
</style>

本文上下两篇链接 《Vue 开发规范(上)》 《 Vue 开发规范(下)》 连载阅读体验更佳。

点赞支持、手留余香、与有荣焉,动动你发财的小手哟,感谢各位大佬能留下您的足迹。

11.png

往期精彩推荐

前端常用的几种加密方法

canvas 爬坑路【方法篇】

不懂 seo 优化?一篇文章帮你了解如何去做 seo 优化

canvas 爬坑路【属性篇】

【实战篇】微信小程序开发指南和优化实践

聊一聊移动端适配

前端性能优化实战

聊聊让人头疼的正则表达式

获取文件blob流地址实现下载功能

Vue 虚拟 DOM 搞不懂?这篇文章帮你彻底搞定虚拟 DOM

Git 相关推荐

通俗易懂的 Git 入门

git 实现自动推送

面试相关推荐

前端万字面经——基础篇

前端万字面积——进阶篇

更多精彩详见:个人主页