注册

Vue 开发规范(中)

上一篇:https://www.imgeek.org/article/825358938

将 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>


作者:_Battle
链接:https://juejin.cn/post/7023548108214648863

0 个评论

要回复文章请先登录注册