115 lines
2.3 KiB
Vue
115 lines
2.3 KiB
Vue
<template>
|
|
<div class="fuzzy-picker">
|
|
<input type="text" v-model="searchText" @input="handleInput" placeholder="输入关键字进行搜索"
|
|
/>
|
|
<div class="dropdown" v-if="showDropdown" @click.stop>
|
|
<ul>
|
|
<li v-for="item in filteredList" :key="item.code" @click="selectItem(item)">
|
|
{{ item.name }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'FuzzyPicker',
|
|
props: {
|
|
parentIndex: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
list: {
|
|
type: Array,
|
|
required: true
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
searchText: '',
|
|
showDropdown: false,
|
|
filteredList: [],
|
|
}
|
|
},
|
|
methods: {
|
|
handleInput() {
|
|
// 根据输入的关键字进行模糊搜索
|
|
this.filteredList = this.list.filter(item =>
|
|
item.name.includes(this.searchText)
|
|
);
|
|
this.showDropdown = true;
|
|
},
|
|
selectItem(item ) {
|
|
// 选中某个列表项并返回
|
|
this.searchText = item.name; // 将选中项的名称赋值给输入框
|
|
this.showDropdown = false;
|
|
this.$emit('select', item , this.parentIndex );
|
|
},
|
|
showList() {
|
|
this.showDropdown = true;
|
|
},
|
|
hideList() {
|
|
this.showDropdown = false;
|
|
},
|
|
mounted() {
|
|
// 添加全局点击事件监听器
|
|
window.addEventListener('click', this.handleOutsideClick);
|
|
},
|
|
|
|
beforeUnmount() {
|
|
// 移除全局点击事件监听器
|
|
window.removeEventListener('click', this.handleOutsideClick);
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.fuzzy-picker {
|
|
position: relative;
|
|
}
|
|
|
|
.dropdown {
|
|
max-height: 180px; /* 设置下拉框容器的最大高度 */
|
|
overflow-y: auto; /* 显示垂直滚动条 */
|
|
position: absolute;
|
|
background-color: #fff;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
width: 100%;
|
|
text-align: center;
|
|
overflow-y: auto;
|
|
z-index: 9999;
|
|
}
|
|
|
|
ul {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.item {
|
|
height: 60px;
|
|
line-height: 60px;
|
|
padding: 0 10px;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s;
|
|
}
|
|
|
|
.divider {
|
|
border-bottom: 1px solid #ccc;
|
|
}
|
|
|
|
.fade-enter-active,
|
|
.fade-leave-active {
|
|
transition: opacity 0.2s;
|
|
}
|
|
|
|
.fade-enter,
|
|
.fade-leave-to {
|
|
opacity: 0;
|
|
}
|
|
</style>
|