解决el-cascader组件下拉选项过长,数据回显无法换行显示的问题
解决el-cascader组件回显数据不换行问题
·
问题描述:
需求是需要一个级联选择框,选择框有一定的高度,当选项比较长的时候,回显数据可以在选择框中不被隐藏,换行显示。el-cascader组件如下,满足不了需求,采用封装组件的方法来实现。
改后效果:

回显数据效果:
代码如下:
1、自定义组件CascaderTextarea.vue
<template>
<div class="cascader-textarea-wrapper">
<!-- 隐藏原生输入框的级联选择器 -->
<el-cascader
v-model="materialName"
:options="options"
:props="props"
@change="handleChange"
ref="cascaderRef"
class="hidden-cascader"
/>
<!-- 自定义文本区域 -->
<textarea
v-model="materialName"
class="custom-textarea"
placeholder="请选择"
@focus="handleFocus"
@click="handleClick"
@input="handleSearch"
rows="3"
></textarea>
</div>
</template>
<script>
export default {
model: {
prop: 'materialName',
event: 'change'
},
props: {
materialName: {
type: String,
default: ''
},
// 接收父组件传递的选项数据
options: {
type: Array,
required: true
},
// 级联选择器配置项(可选)
cascaderProps: {
type: Object,
default: () => ({})
}
},
data() {
return {
selectedValue: [], // 存储实际选择的路径值
displayText: '', // 文本区域显示的内容
props: {
expandTrigger: 'hover',
emitPath: true, // 返回完整路径
...this.cascaderProps // 合并父组件传递的配置
},
filteredOptions: [],
optionsCopy:[],
};
},
methods: {
handleSearch() {
if(this.materialName==''){
this.$emit('change', this.materialName)
this.options=this.optionsCopy;
}
if (!this.materialName) {
this.filteredOptions = [];
return;
}
this.options = this.flattenOptions(this.options)
.filter(option =>
option.label.includes(this.materialName)
);
},
flattenOptions(options, parent = null) {
return options.reduce((acc, option) => {
const flatOption = {
...option,
parent
};
if (option.children) {
return [
...acc,
flatOption,
...this.flattenOptions(option.children, option)
];
}
return [...acc, flatOption];
}, []);
},
// 处理值变化(同步显示文本)
handleChange(value) {
if (!value || value.length === 0) {
this.displayText = '';
return;
}
// 获取选中节点的标签路径
const node = this.$refs.cascaderRef.getCheckedNodes()[0];
if (node) {
this.displayText = node.pathLabels[ node.pathLabels.length - 1];
}
this.$emit('change', this.displayText)
},
// 聚焦时展开下拉框
handleFocus() {
if(this.optionsCopy.length==0){
var objStr= JSON.stringify(this.options);
this.optionsCopy=JSON.parse(objStr);
}
this.$refs.cascaderRef.toggleDropDownVisible(true);
},
// 点击时展开下拉框
handleClick() {
if(this.optionsCopy.length==0){
var objStr= JSON.stringify(this.options);
this.optionsCopy=JSON.parse(objStr);
}
this.$refs.cascaderRef.toggleDropDownVisible(true);
},
},
};
</script>
<style scoped>
.cascader-textarea-wrapper {
position: relative;
}
/* 隐藏原生输入框 */
.hidden-cascader {
position: absolute;
opacity: 0;
pointer-events: none;
}
/* 自定义文本区域样式 */
.custom-textarea {
width: 100%;
padding: 8px 15px;
border: 1px solid #dcdfe6;
border-radius: 4px;
resize: vertical;
font-family: inherit;
font-size: 14px;
transition: border-color 0.2s;
min-height: 80px;
height: 200px;
text-align: center;
}
.custom-textarea:focus {
outline: none;
border-color: #409eff;
}
</style>
2、测试页面
<template>
<div>
<div class="container">
<cascader-textarea
:options="cascaderOptions"
:cascader-props="{ label: 'name', value: 'value' }"
v-model="materialName"
/>
</div>
</div>
</template>
<script>
import CascaderTextarea from './CascaderTextarea.vue';
export default {
components: { CascaderTextarea },
data() {
return {
materialName:'五月五,粽叶香,愿您的生活如糯米般甜糯,如红枣般红火!端午安康,岁岁平安,百事‘粽’顺,幸福‘粽’在身边',
cascaderOptions: [
{
value: 1,
name: '东南',
children: [
{ value: 11, name: '五月五,粽叶香,愿您的生活如糯米般甜糯,如红枣般红火!端午安康,岁岁平安,百事‘粽’顺,幸福‘粽’在身边' },
{ value: 12, name: '艾草青青挂门楣,龙舟竞渡逐浪飞。愿君端午享安康,吉祥如意永相随。记得吃粽佩香囊,千年习俗暖心扉' }
]
},
{
value: 2,
name: '华南',
children: [
{ value: 21, name: '广东' },
{ value: 22, name: '海南' }
]
}
]
};
},
methods: {
}
};
</script>
<style scoped>
/deep/ .classRed .custom-textarea{
background-color: #00FFFF;
}
.container{
margin: auto;
width: 10%;
margin-top: 10%;
height: 300px;
}
</style>
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)