<template>
|
<div class="drop-down-search" @click.stop>
|
<view style="display: flex; align-items: center;">
|
<!-- <u--input v-model="username"
|
clearable
|
maxlength="32"
|
type="text"
|
placeholder="请输入手机号"
|
prefixIcon="account"
|
prefixIconStyle="font-size: 22px;color: #909399"></u--input> -->
|
<input
|
@focus="handleFocus"
|
@blur="closeDropDown"
|
:style="{height: '100%', paddingRight: clear? '60rpx' : '16rpx', display: 'flex'}"
|
type="text"
|
v-model="searchText"
|
@input="handleSearch"
|
:placeholder="placeholder"/>
|
|
<text v-if="searchText.length && clear" @click="handleClearInput" class="iconfont icon-shanchu"></text>
|
<view
|
@click="handleDropDownBox"
|
v-if="icon"
|
:class="['dropdown-container', { rotated: isDropDownVisible}]"
|
></view> <!-- 添加小三角图标 -->
|
</view>
|
|
<scroll-view
|
:scroll-y="true"
|
class="dropdown-scroll"
|
:style="{ maxHeight: (isDropDownVisible && hasOptions) ? dropdownHeight + 'rpx' : '0rpx' }">
|
<div class="dropdown-content">
|
<div v-for="(option, index) in filteredOptions" :key="index" class="option" @click="selectOption(option, $event)">
|
{{ option.username }}
|
</div>
|
</div>
|
</scroll-view>
|
|
</div>
|
</template>
|
|
<script>
|
export default {
|
props: {
|
options: {
|
type: Array,
|
default: []
|
},
|
value: {
|
type: [String, Number],
|
default: ''
|
},
|
dropdownHeight: { // 下拉框的高度
|
type: Number,
|
default: 200
|
},
|
placeholder: {
|
type: String,
|
default: ''
|
},
|
icon: {
|
type: Boolean,
|
default: true
|
},
|
clear: {
|
type: Boolean,
|
default: true,
|
}
|
},
|
data() {
|
return {
|
searchText: this.value.toString(), // 默认将数字转字符串
|
isDropDownVisible: false,
|
hasOptions: false,
|
};
|
},
|
computed: {
|
// 根据搜索文本过滤选项
|
filteredOptions() {
|
return this.options.filter(option =>{
|
if(this.searchText.username){
|
return option.username.toLowerCase().includes(this.searchText.username.toLowerCase())
|
}else{
|
return option.username.toLowerCase().includes(this.searchText.toLowerCase())
|
}
|
}
|
);
|
}
|
},
|
watch: { // 监听 options 数组,要是输入的东西没有,就关闭下拉框
|
searchText() {
|
this.hasOptions = (this.filteredOptions.length > 0)
|
},
|
},
|
mounted() {
|
// 添加点击外部关闭下拉框的事件监听器
|
// document.addEventListener('click', this.closeDropDown.bind(this));
|
},
|
methods: {
|
handleClearInput() { // 清除 input 输入框内容
|
this.searchText = ''
|
this.$emit('input',''); // 向父组件传递选中的值 // 重新获取新的数据
|
},
|
handleDropDownBox() { // 控制三角图表事件
|
this.isDropDownVisible = !this.isDropDownVisible
|
this.hasOptions = (this.filteredOptions.length > 0)
|
},
|
// 处理搜索事件
|
handleSearch(e) {
|
this.$emit('input', e.target.value); // 向父组件传递选中的值
|
this.isDropDownVisible = this.hasOptions;
|
},
|
handleFocus() {
|
this.isDropDownVisible = true;
|
this.hasOptions = true;
|
},
|
// 选择选项
|
selectOption(option, event) {
|
event.stopPropagation();
|
// 处理选项选择逻辑,比如触发事件、更新绑定值等
|
this.searchText = option.username; // 选中选项后更新搜索文本
|
this.isDropDownVisible = false; // 隐藏下拉框
|
this.hasOptions = false;
|
this.$emit('changeInput', option); // 向父组件传递选中的值
|
},
|
// // 获取当前输入的值
|
// getSearchText() {
|
// return this.searchText;
|
// },
|
closeDropDown() {
|
// 点击事件的目标不包含搜索框或下拉框时,隐藏下拉框
|
// this.isDropDownVisible = true;
|
// this.hasOptions = true;
|
if (!this.$el||!this.$el.contains(event.target)) {
|
this.isDropDownVisible = false;
|
}
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.drop-down-search {
|
position: relative;
|
height: 100% !important;
|
}
|
|
.dropdown-scroll {
|
position: absolute;
|
top: calc(100% + 12rpx);
|
left: 0;
|
width: 100%;
|
background: #fff;
|
z-index: 99;
|
/* border: 1rpx solid #ccc; */
|
box-shadow: 0 14rpx 30rpx rgb(0, 0, 0, 0.1);
|
transition: max-height 0.3s ease;
|
}
|
|
.dropdown-content {
|
padding: 10rpx;
|
}
|
|
.option {
|
padding: 10rpx;
|
cursor: pointer;
|
border-bottom: 1rpx solid #ccc;
|
}
|
|
input {
|
width: 100%;
|
padding: 10rpx;
|
box-sizing: border-box;
|
}
|
|
.iconfont {
|
position: absolute;
|
top: 50%;
|
right: 55rpx;
|
font-size: 50rpx;
|
transform: translateY(-50%);
|
font-size: 20rpx;
|
color: #999;
|
cursor: pointer;
|
}
|
.dropdown-container {
|
position: relative;
|
width: 30rpx;
|
height: 30rpx;
|
margin-right: 10rpx;
|
transform: rotate(180deg);
|
}
|
|
.dropdown-container::before {
|
content: '';
|
position: absolute;
|
top: 50%;
|
left: 50%;
|
transform: translate(-50%, -50%);
|
width: 0;
|
height: 0;
|
border-left: 15rpx solid transparent;
|
border-right: 15rpx solid transparent;
|
border-bottom: 15rpx solid #ccc; /* 使用border-bottom创建向下的三角形 */
|
transition: transform 0.3s ease; /* 添加过渡效果 */
|
}
|
|
.rotated::before {
|
transform: translate(-50%, -50%) rotate(180deg); /* 旋转三角形 */
|
}
|
</style>
|