自定义el-select,包含内容有:
1、自定义select后缀图标,清除默认边框,限定下拉框宽度时,内容显示省略号,鼠标经过内容,显示title全部信息
2、鼠标经过select上方显示el-tooltip内容,自定义el-tooltip样式背景为透明色
显示效果:
<template>
<div>
<!-- raw-content:content 中的内容是否作为 HTML 字符串处理,如</br>显示为换行
effect="customized":自定义主题
-->
<el-tooltip
:visible="visible"
trigger="hover"
placement="top"
:content="tipContent || props.placeholder"
raw-content
effect="customized"
>
<div
class="select-option"
@mouseenter="mouseenter"
@mouseleave="mouseleave"
>
<el-select
v-model="value"
filterable
@change="handleChange"
@visible-change="visibleChange"
:title="props.placeholder"
class="m-2"
:placeholder="props.placeholder"
suffix-icon="none"
size="small"
>
<el-option
v-for="(item, index) in props.option"
:key="index"
:label="item.label"
:value="item.value"
:title="item.label"
:class="props.optionWidth"
/>
</el-select>
<p
class="select-icon"
:style="{
transform: selectIconStyle ? 'none' : 'rotate(180deg)',
top: selectIconStyle ? '3px' : '-1px'
}"
/>
</div>
</el-tooltip>
</div>
</template>
<script setup lang="ts">
import { ref, watch, nextTick, computed } from "vue";
const props = defineProps({
// 下拉选项列表
option: {
type: Array,
default() {
return [];
}
},
// 下拉选项框的宽度样式,默认不定义,定义后超出设置宽度则省略号显示,鼠标放上去显示title全部内容
optionWidth: {
type: String,
default: ""
},
// Tooltip默认内容
placeholder: {
type: String,
default: ""
},
// 父组件选中项绑定值
value: {
type: String,
default: ""
}
});
let value = ref(""); // 选中项绑定值
const visible = ref(false); // Tooltip是否可见
const selectIconStyle = ref(true); // 后缀图标状态样式
const tipContent = computed(() => {
// Tooltip内容
if (props.option.length > 0) {
for (const i in props.option) {
const obj = props.option[i];
if (obj["value"] === value.value) {
// 根据下拉选项的value值匹配显示的label值
return obj["label"];
} else {
return;
}
}
} else {
return;
}
return "";
});
// 鼠标移入
function mouseenter() {
// tooltip内容字符大于5的时候显示tooltip
if (tipContent.value && tipContent.value.length > 5) {
visible.value = true;
}
}
// 鼠标移出
function mouseleave() {
// 隐藏tooltip
visible.value = false;
}
// 传值父组件
const emit = defineEmits(["change"]);
// 选中值发生变化时触发
const handleChange = () => {
emit("change", value.value);
};
// 下拉框出现/隐藏时触发
const visibleChange = val => {
if (val) {
selectIconStyle.value = false;
} else {
selectIconStyle.value = true;
}
};
// 监听父组件的传值,同步到下拉选项值
watch(
() => props.value,
val => {
nextTick(() => {
value.value = val;
});
},
{
deep: true,
immediate: true
}
);
</script>
<style scope lang="scss">
.select-option {
position: relative;
// 清除select默认外边框
.el-input__wrapper,
.el-input__wrapper:hover {
box-shadow: none;
}
.el-select {
--el-select-input-focus-border-color: "#ffffff";
--el-select-border-color-hover: "#ffffff";
}
}
// 清除默认后缀图标
:deep(.el-select__icon) {
display: none;
}
// 自定义后缀图标样式(这里是▽)
.select-icon {
position: absolute;
border: 4px solid transparent;
border-top-color: #303133;
margin-top: 15px;
right: 5px;
line-height: 8px;
transition: transform 0.3s;
}
// 自定义tooltip样式,背景颜色透明
.el-popper.is-customized {
border-radius: 4px 4px 4px 4px;
border: none;
background: rgba(0, 0, 0, 0.75);
font-size: 12px;
font-weight: 400;
color: #e6e8eb;
line-height: 18px;
}
:deep(.el-popper.is-customized .el-popper__arrow::before) {
background: rgba(0, 0, 0, 0.75);
}
</style>
组件使用:
<template>
<SelectOption
:value="value"
:option="option"
@change="changeOption"
:placeholder="'抖音客服'"
class="w-[85px]"
/>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import SelectOption from "./selectOption.vue";
const value =ref("")
const option =ref([{
label:"抖音客服助手1",
value:"0",
},{
label:"抖音客服助手2",
value:"0",
}
])
function changeOption(val){
value.value=val
}