part2中我们已经了解一个单文件组件中的script部分怎么写。那么现在我们就来实践一下,尝试写一个简单的UI组件-button。
写UI组件之前,一定记得划定功能范围
如果是在实际项目上写UI组件,首先要注意一点就是不要做过多的假设。项目和项目之间UI风格差别可能非常大,你不可能一次性写好一套UI组件,靠着它走天下。然而同一个项目的风格一定是会保持一致的,所以这里我们说的不做过多假设的意思是,将UI组件的功能范围限定在本项目之中,做到刚好满足需求即可。因此在动手写一个通用组件之前,我的经验是可以和UX沟通下,确认在这个项目中,他对这个按钮设计了哪些方案。
通用组件三剑客: props, event, slot
所谓UI组件,可以理解为一类不带任何业务逻辑的,功能性组件,如按钮,按钮组,输入框,tab等等。它们应具有设计好的样式,显示一些内容,可以响应一些事件(但不处理)。在写组件之前,我们需要知道通用组件三剑客props, event, slot是做什么的。
props用于配置组件的属性
part2中我们说过,vue中父组件通过props向子组件传递数据。在一个UI组件中,我们可能为它设置了某些属性,如是否禁用,颜色,类型等等。在使用时,就可以依靠props来指定属性。比如,我们对button设计了如下属性:
- disabled: boolean, 默认为false;为true时按钮被禁用,并且显示禁用样式
- type: warning/success/primary/normal/opacity,与UX沟通按钮可能的样式。选择不同的type按钮将会显示不同的样式
我们是写组件时,设计了disabled, type两个属性,并且为它们提供了可选项。用户在使用这个组件时,会按照他自己的需求,通过props来指定button组件应该体现什么样式。
|
|
如上,假设我们在父组件中就会得到一个被禁用的success按钮。
event是UI组件向父组件传递的通知
props是从父到子的,相反从子到父就要用到event了。event用于告知父组件,发生了什么事情。
要知道我们自定义的组件并不像原生HTML标签一样默认绑定了onclick等事件,对于我们自定义的vue组件,其上绑定的所有事件都来自于自组件的提交(emit)。
举个栗子,比如对于button,我们最关心的事情就是click事件。在button被用户点击之后,它需要通知父组件“我被点击了哦”,然后在父组件监听到事件后,再去做一些事情。在这里要注意,为了复用,UI组件上不涉及任何业务逻辑的。比如对于click事件,button组件本身并不关系自己被点击之后会有什么后续操作,它只需要将click这件事传递到父组件。
我们监听了子组件中button的click事件,当被点击的时候执行handleClickButton,他做的唯一一件事就是将‘click’事件提交(emit)给父组件(同时可以传参)。然后,我们在父组件中监听‘click’,当被点击的时候执行doSomeThing。
这样,就完成了从子到父的通信。
slot是插槽,用于为父组件中用户自定义的内容做占位。
比如对一个原生的
//button组件
//在父组件中使用button组件
|
|
//button组件
//在父组件中使用button组件
|
|
//button组件
//在父组件中使用button组件
```
父组件里面标签中指定了slot名字的(包括其子元素),会被插入到对应名字到slot位置上;没有名字的标签会被插入的默认的slot中。
上栗中,‘我是按钮’会被插入到 <slot />
处;<img slot="pic"/>
会被插入到`<slot name="pic" />
处`。
简单UI组件的总结
- 开始写UI组件之前,划定功能需求范围
- 不要做太多的假设
- 只响应数据,不处理业务逻辑
- 善用slot, props, event, 让你的组件更灵活
本节我们讲的是最最简单的一个UI组件,用slot, props, event就可以完成需求。但是事实上存在很多复杂得多的情况,需要用到更多vue的小技巧。之后我们会先讲述vue中组件间通讯的其他方式,然后再来尝试更复杂的栗子。