话不多说,先上效果图
这里是将它变成一个组件去使用,可以多个页面引入使用
一.模板界面部分
<!-- :style="{'width':_width,'height':_height}" -->
<template>
<div class="about">
<el-select ref="select" v-model="selectVal" :disabled="disabled" :placeholder="placeholders" size="mini"
:style="{ width: widths }" @blur="clearData" clearable @visible-change="visibleChange" @clear="clearSelect">
<!-- // 设置一个input框用作模糊搜索选项功能 -->
<el-input v-model="keyWordFilter" class="input" placeholder="此处键入'关键词'搜索查询" prefix-icon="el-icon-search"
@input="handleInput" @clear="clear" clearable :validate-event="false"></el-input>
<!-- // 设置一个隐藏的下拉选项,选项显示的是汉字label,值是value //
如果不设置一个下拉选项,下面的树形组件将无法正常使用 -->
<el-option key="id" hidden :value="selectVal" :label="selectVal">
</el-option>
<div ref="container" class="down">
<ul ref="list">
<li class="liFlex" v-for="(item, index) in searchList" :key="index" @click.stop="handleSearchList(item)"
:style="{ background: isActive(item) ? '#f5f7fa' : '#fff' }">
<span>{{ item.number }}</span> <i v-if="isActive(item)" class="el-icon-check right-icon"></i>
</li>
<li v-show="searchResult" style="text-align: center">暂无搜索结果</li>
<li v-if="loading" style="text-align: center">加载中...</li>
</ul>
</div>
<!-- <div v-show="searchResult">暂无搜索结果</div> -->
</el-select>
</div>
</template>
<script>
import { getBelong } from "@/api/ctm/ctm-add";
import { getServiceNumber } from "@/api/admin/sys-user";
export default {
name: "Dorpdown",
props: {
url: {
type: String,
default: () => null,
},
widths: {
type: String,
default: () => null,
},
disabled: {
type: Boolean,
default: () => false,
},
placeholders: {
type: String,
default: () => null,
},
value: {
type: [String, Number, Object],
default: null
},
},
data () {
return {
selectVal: "", // select框的绑定值
selectName: "", // select框显示的name
keyWordFilter: "", // 搜索框绑定值,用作过滤
solist: [], // 搜索存储列表
searchList: [], // 接口返回搜索
loading: false,
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
keyword: "",
},
// 总条数
total: 0,
searchResult: false,
timer: null,
selectVal2: ''
};
},
watch: {
keyWordFilter: {
handler (v) {
if (!v) {
this.searchResult = false;
this.searchList = [];
}
},
},
value: {
// 父组件使用选择的值回显给子组件
immediate: true,
handler (newValue) {
this.selectVal = newValue;
}
},
searchResult (n) {
console.log(n);
},
},
mounted () {
this.$nextTick(() => {
this.scrollToBottom();
});
},
beforeDestroy () {
// 移除滚动事件监听
window.removeEventListener("scroll", this.handleScroll, true);
},
methods: {
isActive (item) {
return this.selectVal === item.number; // 这里的判断条件可以根据具体情况来定
},
scrollToBottom () {
const container = this.$refs.container;
const list = this.$refs.list;
// 滚动到底部
list.scrollTop = container.offsetHeight - list.offsetHeight;
// 监听滚动事件
list.addEventListener("scroll", this.handleScroll);
},
handleScroll () {
const container = this.$refs.container;
const list = this.$refs.list;
// 判断是否滚动到底部
if (
list.scrollTop >=
container.offsetHeight - 60 // 在底部前10像素进行判断,可根据需要调整
) {
console.log(list.offsetHeight, "list.offsetHeight");
// 在这里执行滚动到底部后的逻辑
// console.log(this.searchList.length, "this.searchList.length");
if (this.searchList.length < this.total) {
this.queryParams.pageIndex++;
this.search();
}
}
},
clearData () {
this.keyWordFilter = "";
this.queryParams.pageIndex = 1;
},
visibleChange (e) {
if (!e) {
this.searchList = [];
this.clearData();
} else {
this.search();
}
},
// 根据关键字搜索
handleInput () {
if (this.timer) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
this.searchList = [];
this.queryParams.pageIndex = 1;
this.queryParams.pageSize = 30;
this.search();
}, 300);
},
// 模拟搜索防抖
async search () {
this.queryParams.keyword = this.keyWordFilter;
this.loading = true;
let res;
if (this.url === "addCtm") {
res = await getBelong(this.queryParams);
} else {
res = await getServiceNumber(this.queryParams);
}
if (res.code === 200) {
console.log(res.data.list, 'res.data.list');
this.searchList = [...this.searchList, ...res.data.list];
const map = new Map();
const uniqueList = this.searchList.reduce((acc, item) => {
if (!map.has(item.userId)) {
map.set(item.userId, true);
acc.push(item);
}
return acc;
}, []);
this.searchList = uniqueList
this.loading = false;
console.log(this.searchList, "dorpdown");
if (this.searchList.length === 0) {
this.searchResult = true;
} else {
this.searchResult = false;
}
this.total = res.data.count;
}
},
// 搜索框图标清空
clear () {
this.searchList = [];
this.queryParams.pageIndex = 1;
this.queryParams.pageSize = 20;
},
// 搜索列表点击
handleSearchList (item) {
this.selectVal = item.number;
// this.selectVal=item.userId
item.jobNumber = item.number;
this.selectVal2 = item;
this.$emit("modelClass", this.selectVal2);
// this.$emit('input', this.selectVal);
this.visibleChange();
this.$refs.select.blur();
},
// 清空值v-model的select值
clearSelect () {
this.selectVal = "";
this.selectVal2 = ''
this.$emit("modelClass", this.selectVal2);
},
// 这个给父组件调用,因为上面那个有emit,父组件使用$refs来访问的时候会报错,不是一个方法
newClearSelect () {
this.selectVal = "";
this.selectVal2 = ''
}
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-scrollbar__bar {
overflow-x: hidden;
}
::v-deep .el-input--mini .el-input__inner {
height: 32px;
}
.input {
width: 278px;
margin: 10px;
}
.down {
width: 298px;
max-height: 160px;
ul {
width: 298px;
max-height: 160px;
overflow-y: scroll;
margin: 0;
padding: 0 12px;
list-style: none;
&::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px;
/*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
}
&::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
background: #cccccc;
box-shadow: inset 0 0 5px #cccccc;
}
//滚动条底层颜色!
&::-webkit-scrollbar-track {
border-radius: 10px;
background: #fdf8f5;
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1);
}
li {
overflow: hidden; // 溢出隐藏
white-space: nowrap; // 强制一行
text-overflow: ellipsis; // 文字溢出显示省略号
cursor: pointer;
color: #606266;
padding: 4px 0;
&:hover {
// color: rgb(0, 81, 255);
background: #f5f7fa;
}
}
.liFlex{
display: flex;
justify-content: space-between;
}
}
}
</style>
页面引入
import dorpdown from "../component/dorpdown.vue";
<el-col :span="6">
<el-form-item label="归属工号" prop="belong">
<!-- :placeholders="belong" -->
<dorpdown ref="childDown" :widths="widths" :disabled="disableds" :url="'addCtm'"
:value="diaForms.number" @modelClass="changeModelClass">
</dorpdown>
</el-form-item>
</el-col>
// 工号下拉搜索选择事件
changeModelClass (e) {
this.diaForms.belong = e.number;
this.selectUserId = e.userId;
},