背景
我就职的这家公司主要是为国内的大中小型工业企业提供无人值守方案的,每年都会做大量的项目,几年下来,积累了客观的基于项目的代码库,为了提升开发效率,沉淀解决相同业务的公共组件就势在必行了,这也是本文的开端,也是想要实现的效果,本文将会以下拉选择+弹窗选择为例,来尝试说明:
- What 什么是公共业务组件,和公共组件的区别是什么
- Why 为什么要沉淀公共业务组件
- How 如何沉淀一个公共业务组件
公共组件与公共业务组件的区别
在开始之前,需要讲清楚一个概念,就是公共组件与公共业务组件的区别,顾名思义,公共组件就是类似ANTD
、ElemntUI
等等提供的组件,这些组件通常实现了常见的交互需求但是无关业务,公共业务组件则不同,公共业务组件是为了实现某类特定需求而对公共组件进行了有机组合,接下来,我们就通过2W1H
分析法,来尝试阐述我们如何进行公共业务组件的设计和沉淀
为什么要沉淀公共业务组件
当一个需求反复在我们的项目中出现,而不同的项目里交互和所要实现的功能基本一致,仅仅是展示和要提交的字段不一样的时候,我们就需要考虑针对这个需求定制一个公共业务组件了,现在我们有一个这样的需求,我们希望可以模糊搜索客户档案,物料档案,通过下拉的方式选择,然后也可以弹窗查看更多的列,然后勾选选择。如果没有一个公共的业务组件,那就意味着,我们为了适配物料档案,需要写一套代码,为了适配客户档案,又需要写一套代码,这么来看,沉淀一个公共的业务组件是合理的,接下来,我们就围绕这个需求,基于ElementUI
来实现一个公共业务组件。
样式参考
下拉样式
弹窗样式
如何沉淀一个公共业务组件
共性需求提取
- 一个可以模糊搜索的下拉框
- 下拉框选项内容是动态的
- 右边有一个可以进行弹窗的图标
- 弹窗里的字段是动态的
需求分析
- 模糊搜索的下拉框本身
ElementUI
就支持 - 下拉选项的内容
el-select
提供了默认的插槽 - 弹窗图标
el-select
没有提供插槽,需要我们自行实现 - -弹窗字段动态与下拉选项内容动态本质上需要解决的问题是一样的,就是我们需要一个模板
模糊搜索的下拉框
<el-select filterable remote :remote-method="querySearch">...</el-select>
- 设计展示模板所需要的属性
{
fieldName: 'id', // 后台字段名
fieldTitle: 'id', // 展示的字段名
isLabel: false, // 是否是选择以后展示在下拉框里的字段
isValue: false, // 是否是选择以后要提交给后台的字段,
isQuick: false, // 是否参与输入框的模糊查询(这是要解决既模糊搜名称也要模糊搜编码的需求)
isSelectShow: false, // 是否在下拉选项内展示当前字段
}
- 设计需要从外部传入的属性
props: {
//是否禁用
disabled: {
type: Boolean,
default: false
},
// 是否多选
multiple: {
type: Boolean,
default: null
},
// 要解析的模板
temp: {
},
// 传入的默认值
defaultVal:{
type: [String,Number,Array],
default: null
}
}
- 根据传入的模板对模板进行解析处理选项默认插槽 选项由一个不可编辑的模板表头循环和实际数据循环构成。
<el-select filterable remote :remote-method="querySearch">
// 模板表头循环
<el-option
disabled
label=""
value="title"
>
<div class="flex jus-between">
<div
class="p-l-5 p-r-5 w-125px text-over"
v-for="item in selectHeader"
:key="item.fieldName"
>
{{ item.fieldTitle }}
</div>
</div>
</el-option>
// 真正的数据循环
<el-option
v-for="(record, index) in tableData"
:label="record[labelKey]"
:value="record[valueKey]"
:key="index"
>
<div class="flex jus-between">
<div
class="p-l-5 p-r-5 w-125px text-over"
v-for="item in selectHeader"
:key="item.fieldName"
>
<span>
{{ record[item.fieldName] }}
</span>
</div>
</div>
</el-select>
computed: {
// 需要在选项内展示的列
selectHeader () {
return this.temp.filer(v => v.isSelectShow)
}
}
- 弹窗图标的实现 我们需要一个容器,提供定位属性,然后将弹窗图标与
el-select
放在容器里,通过:deep 与相邻元素选择器,来定义我们的公共业务组件的样式
<div class="refer-modal-box">
<div
@click.stop.self="showReferModal"
class="iconfont icon-loadmore cursor loadmore"
/>
<el-select
...
...
.refer-modal-box{
padding-right: 30px;
position: relative;
// 这里top为1px的原因是input高度比总高度低1像素,通过定位来拉伸高度。
.loadmore{
width: 30px;
color: #999;
text-align: center;
border-radius: 4px;
border: 1px solid #dcdfe6;
position: absolute;
top: 1px;
bottom: 0;
right: 0;
margin: auto;
box-sizing: border-box;
border-left: 0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
// 相邻元素选择器定义input样式,与弹窗图标一起拼成一个完整边框
.loadmore ~ .el-select:deep(input){
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-color: #dcdfe6;
}
.loadmore:hover{
color: #2e79ef;
}
}
对外暴露的事件
事件我们可以提供一个获取当前选中值的方法,在组件外通过$refs.referModal.getChecked()
来获取,$refs.组件名可以直接拿到组件的vue实例,当然可以调用声明在methods内的方法
总结
- 公共业务组件沉淀的必备基础 技术体系已经完成了收敛和统一
- 公共业务组件沉淀的时机: 当某个需求多次出现,而现有的基础组件无法cover的时候
- 公共业务组件沉淀的标准: 满足当下已经出现的需求点,留出未来可能出现的扩展点,怎么理解这句话呢?我举一个简单的例子,如果一个字段他的字段类型是个布尔值,那么未来他只能是
true
或者是false
, 假如这个字段我们定义成一个枚举值,那未来他就是可以无限扩展的。同理,当我们在处理需要判断的情况时,定义外部传入的prop
尽量是个枚举值而不是布尔值,这样我们的组件解析就存在无限扩展的可能。 - 公共业务组件的属性设计: 要充分评估现存的已经存在于业务代码内的需求,并根据需求去设计我们公共业务组件的属性
- 模板与插槽: 模板本身所起到的作用就是减少重复代码的编写,所以公共业务组件的模板解析放在了组件内而不是通过插槽的方式对外暴露,当然我们也可以预留对应的插槽,那么公共业务组件就变成了仅有样式的壳,真正的业务实现由引用这个公共业务组件的页面决定
综上所述,当你的团队已经完成技术体系的收敛和统一,也就是产品体验一致、框架一致,以及基础技术栈一致时,就已经具备了公共业务组件沉淀的必要基础,经历了长期的小步快跑,快速迭代,按项目交付这样的技术积累后,根据本文的方式去构建公共业务组件库,应该会有不错的效果。
以上就是ToB项目如何沉淀业务公共组件示例详解的详细内容,更多关于ToB项目沉淀业务公共组件的资料请关注编程网其它相关文章!