问题描述:最近遇到一个需求,使用el-cascader组件,单选选择多层级节点后,选择框内展示不全,业务需要全面的节点可以省略,最后一个节点必须全部展示。
但当屏幕比较窄时,输入框内的内容显示不全,右侧会溢出省略
但根据业务的需求,父级节点可以省略,最后一个节点需要完整的展示出来,也就是要把“雁塔区”显示出来,理想效果为
当时查询了资料,只要给el-sascader设置一个style=“direction:rtl;"就可以实现上图效果,但是这么操作引发一个新的问题
选择框里所有的内容都居右了。
为此想到了一个办法,比较内容的长度(contentWidth),和el-cacsader中的input的长度(inputWidth)进行比较,当contentWidth > inputWidth是给el-cascader加上style=“direction:rtl;",否则去掉。
但是如何获取contentWidth呢?
首先想到的办法是,使用字符串长度 和inputWidth/fontSize进行对比
<el-cascader
id="cascader"
ref="cascder"
:options="options"
@change="handleChange"
style="width:100%;"
:props="{ checkStrictly: true }"
clearable>
</el-cascader>
methods: {
handleChange () {
let $input = document.querySelector('#cascader .el-input__inner');
let fz = parsetInt(window.getComputedStyle($input).fontSize);
let inputWidth = parseInt(window.getComputedStyle($input).width);
this.$nextTick(() => {
let checkNode = this.$refs.cascader.getCheckedNodes();
if (checkNode && checkNode.length) {
let labels = checkNode[0].pathLabels.join(',');
if (labels.legnth > inputWidth) {
this.$refs.cascader.$el.querySelector('input').style.direction = 'rtl';
} else {
this.$refs.cascader.$el.querySelector('input').style.direction = 'ltr';
}
}
})
}
}
试了下,有的时候生效有的时候不生效,突然想起font-size实际和高度有关,和宽度没有关系,而且不同的字体的宽度也不同,因此通过字符串长度 和inputWidth/fontSize对比的方式判断是否添加direction无法准确实现需求。
如果生成一个dom,把labels填入,并禁止换行,然后读取长度,是否能实现呢?代码如下:
methods: {
handleChange () {
let $input = document.querySelector('#cascader .el-input__inner');
let inputWidth = parseInt(window.getComputedStyle($input).width);
this.$nextTick(() => {
let checkNode = this.$refs.cascader.getCheckedNodes();
if (checkNode && checkNode.length) {
let labels = checkNode[0].pathLabels.join(',');
setTimeout(() => {
let $div = document.createElement('div');
$div.style = 'white-space:nowrap;';
$div.innerText = labels;
document.body.append($div);
let contentWidth = $div.scrollWidth;
if (contentWidth > inputWidth) {
this.$refs.cascader.$el.querySelector('input').style.direction = 'rtl';
} else {
this.$refs.cascader.$el.querySelector('input').style.direction = 'ltr';
}
$div.remove();
})
}
})
}
}
如上代码解决问题。