话不多说,先上效果图
这里是将它变成一个组件去使用,可以多个页面引入使用
一.模板界面部分
<!-- 这个是下拉带搜索组件
-->
<!-- :style="{'width':_width,'height':_height}" -->
<template>
<div class="about">
<el-select
ref="select"
v-model="selectVal"
:disabled="disabled"
:placeholder="placeholders"
size="mini"
clearable
:style="{ width: widths }"
@blur="clearData"
@visible-change="visibleChange"
>
<!-- // 设置一个input框用作模糊搜索选项功能 -->
<el-input
v-model="keyWordFilter"
class="input"
placeholder="此处键入'关键词'搜索查询"
prefix-icon="el-icon-search"
clearable
@input="handleInput"
@clear="clear"
></el-input>
<!-- // 设置一个隐藏的下拉选项,选项显示的是汉字label,值是value //
如果不设置一个下拉选项,下面的树形组件将无法正常使用 -->
<el-option key="id" hidden :value="selectVal" :label="selectVal">
</el-option>
<div ref="container" class="down">
<ul ref="list">
<li
v-for="(item, index) in searchList"
:key="index"
@click.stop="handleSearchList(item)"
>
{{ item.number }}
</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,
},
},
data() {
return {
selectVal: "", // select框的绑定值
selectName: "", // select框显示的name
keyWordFilter: "", // 搜索框绑定值,用作过滤
solist: [], // 搜索存储列表
searchList: [], // 接口返回搜索
loading: false,
// 查询参数
queryParams: {
pageIndex: 1,
pageSize: 10,
number: "",
},
// 总条数
total: 0,
searchResult: false,
timer: null,
};
},
watch: {
keyWordFilter: {
handler(v) {
if (!v) {
this.searchResult = false;
this.searchList = [];
}
},
},
searchResult(n) {
console.log(n);
},
},
mounted() {
this.$nextTick(() => {
this.scrollToBottom();
});
},
beforeDestroy() {
// 移除滚动事件监听
window.removeEventListener("scroll", this.handleScroll, true);
},
methods: {
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.number = 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) {
this.searchList = [...this.searchList, ...res.data.list];
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 = 10;
},
// 搜索列表点击
handleSearchList(item) {
this.selectVal = item.number;
this.selectVal2 = item;
console.log(this.selectVal2, "aa");
this.$emit("modelClass", this.selectVal2);
// this.$emit("modelOrigin", this.selectVal);
this.visibleChange();
this.$refs.select.blur();
},
// 清空值v-model的select值
clearSelcet() {
this.selectVal = "";
},
},
};
</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: 120px;
ul {
width: 298px;
max-height: 120px;
overflow-y: scroll;
margin: 0;
padding: 0 12px;
list-style: none;
&::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px;
/*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
}
&::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
background: #1890ff;
box-shadow: inset 0 0 5px rgb(59, 193, 230);
}
//滚动条底层颜色!
&::-webkit-scrollbar-track {
border-radius: 10px;
background: #ededed;
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1);
}
li {
overflow: hidden; // 溢出隐藏
white-space: nowrap; // 强制一行
text-overflow: ellipsis; // 文字溢出显示省略号
cursor: pointer;
&:hover {
color: rgb(0, 81, 255);
}
}
}
}
</style>
页面引入使用
const dorpdown = () => import('../component/dorpdown.vue')
<el-col :span="6">
<el-form-item label="归属工号" prop="belong">
<dorpdown
ref="childDown"
:widths="widths"
:url="'addCtm'"
@modelClass="changeModelClass"
></dorpdown>
</el-form-item>
</el-col>
```js
// 下拉搜索选择事件
changeModelClass(e) {
this.form.userId = e.userId;
this.$set(this.form, "belong", e.number);
console.log(this.form.belong, "this.modelClass");
console.log(e.number);
},
// 重置按钮
resetForm(formName) {
this.form = {};
// 直接调用子组件方法清空值
this.$refs.childDown.clearSelcet();
this.$refs.form.resetFields();
// this.$refs[formName].resetFields();
this.$message.success("重置成功");
},
},
文章简洁明了,cv可看效果,希望可以帮助到正在看的你