1.前言写代码有时候就和弹簧加工一样。一个看似简单的物品,加工起来未必简单
最近在做项目的时候,看到有两个功能一样,但是交互,样式不一样的需求,为了图方便维护,就封装了组件,发现一个看似简单的组件,如果要封装得通用些,要考虑的东西其实也不少。
2.先看组件该文章只是举例说明可以从哪些点入手,增加组件的通用性。以及提供一些封装的思路。提及的组件仍然与项目需求有挺大的关系,差不多是针对项目的定制开发,在其他项目上可能还不能开箱即用,要使用的话,还需要对组件进行修改。
这个组件看着就很简单,一下就写好了
出于篇幅的考虑,css ,以及一些不关联的 js 代码就不提供了,需要看源码可以移步: 文章例子源码:HandleButtonOld,项目完整代码:项目代码
HandleButtonOld.vue
// 略
3.改进优化
组件用起来也很简单,简单一行代码就出来了
sortData
sortdata: [
{
fileType: 'text',
content: '前端开发',
index: 2,
size: 12
},
{
fileNmae: '251bb6d882024b11a6051d604ac51fc3.jpeg',
fileType: 'image',
fileUrl:
'https://file-cdn-china.wechatify.net/marketing/sms/mms_material/53ce422f14e516af0eb9a5c7251cc1ca.jpeg',
index: 3,
size: 101109,
fileName: '53ce422f14e516af0eb9a5c7251cc1ca.jpeg'
},
{
fileType: 'text',
content: '守候',
index: 5,
size: 12
}
]
但是如果页面上又有这样一个需求,功能一样,样式排版不一样,比如下图这样
然后组件就无法使用了。
这个时候,肯定不是复制一个文件,改下样式再写一个组件,只能把原来的组件改得通用些,能适合更多需求。
遇到这样的需求,非常不建议复制一个文件,再写一个组件。如果下次再有这种情况,又要再复制一个文件,再写一个组件。就可能会导致组件文件非常多,影响维护
让组件更通用些,能适合更多需求,主要就是要把经常会变的因素抽取出来,交给用户自定义,至于有哪些地方可以改进优化?下面就简单列举一下
3-1.支持自定义内容首页,看到两个需求,排版样式和显示字段就不一样了。不知道以后第三种,第四种排版样式,也不知道会显示什么字段。所以这里最好是他操作按钮抽出来,作为组件封装,至于怎么排版,显示什么字段,组件不管,只需要提供一个 slot 由用户自定义。
HandleButtonOld.vue
页面调用
3-2.支持自定义选中样式{{item.data.content}}123
来到这里,看一下选中的效果,
除了显示几个操作按钮之外,还有一个蓝色的边框线,但是不同需求,选中效果可能是不一样的,比如有一个地方要用灰色双实线,再有一个地方要用白色实现,边距增加 30px 等等。无法猜测下一次用这个组件的时候,选中样式是什么。所以选中样式不能在 handle-button-old 内部写死或者判断,只能让用户自定义。我们能提供的,就是给一个字段,告诉用户哪一项是当前选中的。
HandleButtonOld.vue
//代码略
页面调用
//代码略 .view-item { padding: 10px; border:4px dashed transparent; &.cur{ border:4px double #ccc; } }
这样就可以让用户自定义选中的样式了
3-2.设置操作按钮的显示位置和方向再看一下两个需求的样式
首先看到按钮的位置和方向是不一样的。按钮的位置,可以给默认值,但也要让用户可以自定义。要确定按钮的定位,则 handle-button-old 组件需要提供 top,right,bottom,left,四个参数。为了方便定位,除了可以设置具体像素,百分比之外,还要支持用户输入’center’,方便用户设置垂直或者水平居中。
按钮的方向就需要提供 direction 参数,用户输入 horizontal 就垂直显示,输入 vertical 就水平显示
handle-button-old
//代码略
.ec-handle--item {
position: relative;
ul {
position: absolute;
right: -26px;
top: 0;
display: none;
line-height: 24px;
&.handle-vertical {
li {
display: inline-block;
vertical-align: top;
}
}
}
}
页面调用
//代码略 export default { data () { return { iconByFileType: { text: 'icon-wenben', image: 'icon-tupian1', video: 'icon-shipin', audio: 'icon-yinpin', link: 'icon-duanlian' }, //代码略 } }, //代码略 methods: { formatSize (val) { if (val === 0) { return '0B' } let sizeObj = { MB: 1048576, KB: 1024, B: 1 } val = +val for (let key in sizeObj) { if (val >= sizeObj[key]) { return +(val / sizeObj[key]).toFixed(2) + key } } }, //代码略 } }//代码略
这样效果就实现了
3-3.设置操作按钮的显示方式想必大家已经看到问题了,【3-2】最后看到的结果是只有其中一项是有操作按钮的,而【3-2】一开始,看到的需求是所有的结果都要显示出来。那么这里就要设置一个 display 属性了,设置操作按钮的显示方式。目前提供三个值’default’-选中的项显示,‘visible’-所有项显示,‘none’-不显示。
handle-button-old
//代码略
页面调用
//代码略
这样就能实现了
3-4.点击操作按钮前的触发动作很多人在开发上会遇到一些需求,特别是在执行比如删除,清空等“危险操作”之前,要给一个弹窗或者其他方式的提醒,让用户谨慎操作。而这个组件的操作按钮,也有可能是“危险操作”。所以需要让用户可以自定义操作前的回调。
拿文章提及的 handle-button-old 组件来说,如果需求是“删除”按钮前需要给提醒弹窗,其他的按钮直接操作。
handle-button-old
页面调用
3-5.切换选中的项的触发动作
比如有需求,点击切换选中的时候,需要拿当前项的数据,做为请求的参数。实现这个需求,只需要在 handle-button-old 组件里面需要提供一个自定义事件即可
handle-button-old
methods:{
switchCur (item, index) {
this.nowClickIndex = index
//触发自定义事件
this.$emit('change', item, index)
}
}
页面调用
3-6.取消选中
可能大家在一早已经发现了这个问题,如果选中了某一项,出现了下面情况。
但是如果需求是取消选中呢?那就做不到了。从代码逻辑上来讲,只要选中了,就要选中一项,没办法取消。所以,在 3-5 的 switchCur 函数就需要判断一下,如果点击的是当前项,就取消选中
handle-button-old
methods:{
switchCur (item, index) {
if (this.display === 'visible') {
return
}
// 如果点击的是当前项,就取消选中
this.nowClickIndex = this.nowClickIndex !== index ? index : ''
this.$emit('change', item, index)
}
}
3-7.按钮折叠显示
在上面的图片可以看到,按钮要么是横向排列,要么是竖向排列。如果哪天需求觉得按钮太占位置,需要折叠显示按钮,这个也很简单就可以兼容了,给 handle-button-old 加个 type 参数判断下要根据什么方式显示就可以了。
handle-button-old
操作
编辑
上移
下移
删除
export default {
name: 'HandleButton',
componentName: 'HandleButton',
props: {
type: {
type: String
}
// 代码略
}
// 代码略
}
页面调用
type=“dropdown” 之后,direction 参数会不起效
3-8.按钮显示方式{{item.data.content}}
{{item.data.fileName}}
{{formatSize(item.data.size)}}
回到这个场景,可能大家在开发的时候已经想到了,要出现操作按钮,必须要点击某一项才会出现。但很多时候的需求,需要鼠标 放上去的时候就显示操作按钮,不需要点击。要实现这个,只需要添加 一个 trigger 参数,triggle 默认为 ‘click’-点击出现,‘hover’-鼠标放上去出现
页面调用
3-9.关于其他
首次 handle-button-old 这个组件为例,列举了一些改进优化的功能。如果想折腾,还是有不少功能可以折腾的,比如按钮的样式(图标的颜色、形状、背景颜色、大小等等)、间距,自定义按钮等。至于要不要折腾,就看需求有没有必要了,具体情况,具体分析。文章的这个,还是很简单的一个组件,如果是复杂的组件,需要优化的点可能就更多了。
4.小结封装组件的时候,如果一开始对组件的要求比较单一,或者时间比较紧急,也可以先封装个有基本功能,能满足需求的组件。之后如果发现组件不能满足业务需求了,再进行改进和优化也不迟。


![[举个栗子]增加组件通用性的几个点 [举个栗子]增加组件通用性的几个点](http://www.mshxw.com/aiimages/31/239895.png)
