详解打造 Vue.js 可复用组件

Vue.js 是一套构建用户界面的渐进式框架。我们可以使用简单的 API 来实现响应式的数据绑定和组合的视图组件。

从维护视图到维护数据,Vue.js 让我们快速地开发应用。但随着业务代码日益庞大,组件也越来越多,组件逻辑耦合严重,使代码维护变得十分困难。

同时,Vue.js 的接口和语法十分自由,实现同一功能有若干种方法。每个人解决问题的思路不一样,写出来的代码也就不一样,缺乏团队内的规范。

本文旨在从组件开发的不同方面列举出合理的解决方法,作为建立组件规范的一个参考。

构成组件

组件,是一个具有一定功能,且不同组件间功能相对独立的模块。组件可以是一个按钮、一个输入框、一个视频播放器等等。

可复用组件,高内聚、低耦合。

那么,什么构成了组件呢。以浏览器的原生组件 video 为例,分析一下组件的组成部分。

<video src="https://www.jb51.net/example.mp4" onerror="errorHandler"> Your browser does not support the video tag. </video>

实例中能看出,组件由状态、事件和嵌套的片断组成。状态,是组件当前的某些数据或属性,如 video 中的 src、width 和 height。事件,是组件在特定时机触发一些操作的行为,如 video 在视频资源加载成果或失败时会触发对应的事件来执行处理。片段,指的是嵌套在组件标签中的内容,该内容会在某些条件下展现出来,如在浏览器不支持 video 标签时显示提示信息。

在 Vue 组件中,状态称为 props,事件称为 events,片段称为 slots。组件的构成部分也可以理解为组件对外的接口。良好的可复用组件应当定义一个清晰的公开接口。

Props 允许外部环境传递数据给组件

Events 允许组件触发外部环境的副作用

Slots 允许外部环境将额外的内容组合在组件中。

使用 vue 对 video 组件做拓展,构造出一个支持播放列表的组件 myVideo:

<my-video :playlist="playlist" @load="loadHandler" @error="errorHandler" @playnext="nextHandler" @playprev="prevHandler"> <div slot="endpage"></div> </my-video>

myVideo 组件有着清晰的接口,接收播放列表、播放器宽高等状态,能够触发加载成功或失败、播放上一个或下一个的事件,并且能自定义播放结束时的尾页,可用于插入广告或显示下一个视频信息。

组件间通信

在 Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。看看它们是怎么工作的。

详解打造 Vue.js 可复用组件

业务无关

命名

组件的命名应该跟业务无关。应该依据组件的功能为组件命名。

例如,一个展示公司部门的列表,把每一项作为一个组件,并命名为 DepartmentItem。这时,有一个需求要展示团队人员列表,样式跟刚刚的部门列表一样。显然,DepartmentItem 这个名字就不适合了。

因此,可复用组件在命名上应避免跟业务扯上关系,以组件的角色、功能对其命名。Item、ListItem、Cell。可以参考 Bootstrap、ElementUI 等一些 UI 框架的命名。

业务数据无关

可复用组件只负责 UI 上的展示和一些交互以及动画,如何获取数据跟它无关,因此不要在组件内部去获取数据,以及任何与服务端打交道的操作。可复用组件只实现 UI 相关的功能。

组件职责

约束好组件的职责,能让组件更好地解耦,知道什么功能是组件实现的,什么功能不需要实现。

组件可以分为通用组件(可复用组件)和业务组件(一次性组件)。

可复用组件实现通用的功能(不会因组件使用的位置、场景而变化):

UI 的展示

与用户的交互(事件)

动画效果

业务组件实现偏业务化的功能:

获取数据

和 vuex 相关的操作

埋点

引用可复用组件

可复用组件应尽量减少对外部条件的依赖,所有与 vuex 相关的操作都不应在可复用组件中出现。

组件应当避免对其父组件的依赖,不要通过 this.$parent 来操作父组件的示例。父组件也不要通过 this.$children 来引用子组件的示例,而是通过子组件的接口与之交互。

命名空间

可复用组件除了定义一个清晰的公开接口外,还需要有命名空间。命名空间可以避免与浏览器保留标签和其他组件的冲突。特别是当项目引用外部 UI 组件或组件迁移到其他项目时,命名空间可以避免很多命名冲突的问题。

<xl-button></xl-button> <xl-table></xl-table> <xl-dialog></xl-dialog> ...

业务组件也可以有命令空间,跟通用组件区分开。这里用 st (section) 来代表业务组件。

<st-recommend></st-recommend> <st-qq-movie></st-qq-movie> <st-sohu-series></st-sohu-series>

上下文无关

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwypfy.html