前端:“这需求是认真的吗?” —— el-select 的动态宽度解决方案
点击关注公众号,“技术干货”及时达!
Hello~大家好。我是秋天的一阵风 ~
前言最近我遇到了一个神奇的需求,客户要求对 「el-select」 的 「宽度」 进行动态设置。
简单来说,就是我们公司有一些选择框,展示的内容像“中华人民共和国/广西壮族自治区/南宁市/西乡塘区”这么长,一不小心就会内容超长,显示不全。详情请看下面动图:
一般来说,想解决「内容展示不全」的问题,有几种方法。
第一种:给选择框加个tooltip效果,在鼠标悬浮时展示完整内容。
第二种:对用户选择label值进行切割,只展示最后一层内容。
但是我们的客户对这两种方案都不接受,要求选择的时候让select选择框的宽度动态增加。
有什么办法呢?客户就是上帝,必须满足,他们说什么就是什么,所以我们只能开动脑筋,动手解决。
思路我们打开控制台,来侦察一下el-select的结构,发现它是一个el-input--suffix的div包裹着一个input,如下图所示。
内层input的宽度是100%,外层div的宽度是由这个内层input决定的。也就是说,内层input的宽度如果动态增加,外层div的宽度也会随之增加。那么问题来了,如何将内层input的宽度动态增加呢?
?tips:
如果你对width的100%和auto有什么区别感兴趣,可以点击查看我之前的文章
探究 width:100%与width:auto区别
?解决方案为了让我们的el-select宽度能够跟着内容走,我们可以在内层input同级别增加一个元素,内容就是用户选中的内容。内容越多,它就像一个胃口很大的小朋友,把外层div的宽度撑开。下面来看图示例 :
借助prefix幸运的是,el-select本身有一个prefix的插槽选项,我们可以借助这个选项实现:
我们添加一个prefix的插槽,再把prefix的定位改成relative,并且把input的定位改成绝对定位absolute。最后将prefix的内容改成我们的选项内容。看看现在的效果:
template
div
el-selectclass="autoWidth"v-model="value"placeholder="请选择"
templateslot="prefix"
{{optionLabel}}
/template
el-option
v-for="iteminoptions"
:key="item.value"
:label="item.label"
:value="item.value"
/el-option
/el-select
/div
/template
script
exportdefault{
data(){
return{
options:[
{
value:"选项1",
label:"中华人民共和国/广东省/深圳市/福田区",
},
{
value:"选项2",
label:"中华人民共和国/广西壮族自治区/南宁市/西乡塘区",
},
{
value:"选项3",
label:"中华人民共和国/北京市",
},
{
value:"选项4",
label:"中华人民共和国/台湾省",
},
{
value:"选项5",
label:"中华人民共和国/香港特别行政区",
},
],
value:"",
},
computed:{
optionLabel(){
return(this.options.find((item)=item.value===this.value)||{})
.label;
},
},
};
/script
stylelang="scss"scoped
::v-deep.autoWidth.el-input__prefix{
position:relative;
}
::v-deep.autoWidthinput{
position:absolute;
}
/style
细节调整现在el-select已经可以根据选项label的内容长短动态增加宽度了,但是我们还需要继续处理一下细节部分,将prefix的内容调整到和select框中的内容位置重叠,并且将它隐藏。看看现在的效果
::v-deep.autoWidth.el-input__prefix{
position:relative;
box-sizing:border-box;
border:1pxsolid#fff;
padding:030px;
height:40px;
line-height:40px;
left:0px;
visibility:hidden;
}
调整初始化效果(用户未选择内容)目前已经基本实现了效果了,还有最后一个问题,当用户没有选择内容的时候,select的宽度是“没有”的,如下图所示。
所以我们还得给他加上一个最小宽度
我们加上最小宽度以后,发现这个select的图标又没对齐,这是因为我们在重写.el-input__prefix样式的时候设置了padding: 0 30px,当用户没有选择内容的时候,select的图标应该是默认位置,我们需要继续调整代码,最后效果如下图所示:
完整代码最后附上完整代码:
template
div
el-select
class="autoWidth"
:class="{'has-content':optionLabel}"
v-model="value"
placeholder="请选择"
clearable
templateslot="prefix"
{{optionLabel}}
/template
el-option
v-for="iteminoptions"
:key="item.value"
:label="item.label"
:value="item.value"
/el-option
/el-select
/div
/template
script
exportdefault{
data(){
return{
options:[
{
value:"选项1",
label:"中华人民共和国/广东省/深圳市/福田区",
},
{
value:"选项2",
label:"中华人民共和国/广西壮族自治区/南宁市/西乡塘区",
},
{
value:"选项3",
label:"中华人民共和国/北京市",
},
{
value:"选项4",
label:"中华人民共和国/台湾省",
},
{
value:"选项5",
label:"中华人民共和国/香港特别行政区",
},
],
value:"",
},
computed:{
optionLabel(){
return(this.options.find((item)=item.value===this.value)||{})
.label;
},
},
};
/script
stylelang="scss"scoped
.autoWidth{
min-width:180px;
}
::v-deep.autoWidth.el-input__prefix{
position:relative;
box-sizing:border-box;
border:1pxsolid#fff;
padding:030px;
height:40px;
line-height:40px;
left:
visibility:hidden;
}
::v-deep.autoWidthinput{
position:absolute;
}
.autoWidth{
//当.has-content存在时设置样式
&.has-content{
::v-deep.el-input__suffix{
right:
}
}
//当.has-content不存在时的默认或备选样式
&:not(.has-content){
::v-deep.el-input__suffix{
right:-55px;
}
}
}
/style
点击关注公众号,“技术干货”及时达!
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线