form-item组件封装细讲下(组件库系列~六)

前言

在前两篇文章中,我们已经成功地对form-item组件进行了基本的封装,现在可以在项目中进行使用了。然而,在同一个form表单中,不同表单项的label字段长度有很大差别,比如“姓名”和“身份证号码”。通常情况下,我们会根据最长的文字长度来设定整体的label-width,但这种做法效果并不理想。今天,我们来分享一下如何实现自动设置label-width的方法。

思路分析

将行配置转换为列配置,获取每一列的配置信息。然后,针对每一列,获取当前列中最长字段的长度,并判断是否存在必填规则。基于当前列中最长字段的长度与文字宽度相乘,加上必填项所占的宽度,设置当前列的每一个form-item 的 label-width宽度。

实现方式

使用层:我们先定义好初始化参数,里面能看到label有3、5、7、9个字的。然后呢行位置还不相同。

form: {
    dateTimeRangeSelectVal: [],
    checkboxVal: []
},
config: [
    { label: '选择框', prop: 'selectVal', itemType: 'select' },
    { label: '输入框', prop: 'inputVal', itemType: 'input' },
    { label: '时间选择器', prop: 'dateSelectVal', itemType: 'date-picker', span: 2 },
    { label: '时间日期选择器', prop: 'dateTimeSelectVal', itemType: 'date-picker', type: "datetime" },
    { label: '时间日期阶段选择器', prop: 'dateTimeRangeSelectVal', itemType: 'date-picker', type: "datetimerange", span: 2 },
    { label: '单选框', prop: 'radioVal', itemType: 'radio', list: [{label: '启用', value: 1}, {label: '禁用', value: 0}] },
    { label: '多选框', prop: 'checkboxVal', itemType: 'checkbox', span: 3, list: [{label: 'IOS', value: 1}, {label: '安卓', value: 0}] },
]

在这里插入图片描述

  1. 组件内部处理行转列:
rowList() {
    // rowList每一行的数据,初始化的时候给一个二维数组,并制定第一个参数为new Array()
     const rowList = [new Array(this.realColumn)];
     // count用来计算是否换行新增rowList的数组元素空数组,用来填补二维数组空位
     // rowListSub代表的是rowList的当前操作项的下标
     let count = 0,
         rowListSub = 0;
     this.realConfig.forEach((e, index, arr) => {
         // 未设定span值时默认值为1;
         const span = e.span || 1;
         count += span;
         rowList[rowListSub][count - span] = { ...e, index };
         if (count + ((arr[index + 1] || {}).span || 1) > this.realColumn && arr[index + 1]) {
             rowList.push(new Array(this.realColumn));
             rowListSub++;
             count = 0;
         }
     });
     return rowList;
 },

处理之后的结果:

2. 取出列的宽度配置

columnLabelWidth() {
   // columnList每一列的数据
    const columnList = [];
    // 行数据转列数据
    this.rowList.forEach(e => {
        for (let i = 0; i < e.length; i++) {
            if (!columnList[i]) columnList[i] = [];
            columnList[i].push(e[i]);
        }
    });
    // 取出每一列最大值nameLength
    // 取出每一列的index下标
    return columnList.map(item => {
        return {
            nameLength: Math.max.apply(
                null,
                item.map(items => (items && this.charCode(items.label).length / 4) || 0)
            ),
            indexList: item.map(items => items && items.index),
            hasRules: item.some(items => items && items.label && this.rules[items.prop] && this.rules[items.prop][0].required)
        };
    });
}


得到columnLabelWidth的参数配置之后,我们就可以拿着参数配置进行每一项的label-width宽度设置

<el-form-item
            v-for="(item, index) in realConfig"
            :key="'form-item' + index"
            :label="!noLabel ? item.label : ''"
            :label-width="setWidth(item, index)"
            :prop="item.prop"
            :class="(item.span && 'col-' + colVal * item.span) || `col-${colVal}`"
        >
// 通过columnLabelWidth获取对应index里面的值
setWidth(item, index) {
     if (this.noLabel) return '0px';
     if (!this.sameLabel) return this.labelWidth;
     // 增加rules为入参,判断当前项是否有必填校验,如果有那么width加上11px;
     let val = this.columnLabelWidth.find(e => e.indexList.includes(index));
     const rulesWidth = val.hasRules ? this.rulesWidth : 0;
     return val.nameLength * this.$Config.Components.formItem.labelFontSize + rulesWidth + 16 + 'px';
 },

总结:

通过以上的一些操作处理方法,这样我们就做到了对每一个label-width的自定义设置了。下一节我们来聊一聊tcode字典在项目中的作用.这里我们就已经完整的实现了form-item组件的二次封装了,关于内部的input、select等组件,大家可以通过gitee进行查看。hc-basic组件库已开源。

组件库代码地址

https://gitee.com/yangxiongasin/hc-basic

组件库文档代码地址

https://gitee.com/yangxiongasin/hc-docs

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端杨雄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值