
10 changed files with 533 additions and 115 deletions
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
@ -0,0 +1,185 @@ |
|||||
|
<template> |
||||
|
<el-select width="120px" v-model="selectedValue" v-bind="$attrs" :clearable="clearable" :placeholder="placeholder" |
||||
|
@change="handleChange" @clear="handleClear"> |
||||
|
<!-- 搜索框(当 searchable 为 true 时显示) --> |
||||
|
<template v-if="searchable"> |
||||
|
<el-input v-model="searchText" height="30px" size="small" :placeholder="searchPlaceholder" |
||||
|
class="select-search-input" @input="handleSearch" /> |
||||
|
</template> |
||||
|
|
||||
|
<div class="optionsList"> |
||||
|
<!-- 下拉选项 --> |
||||
|
<el-option v-for="item in filteredOptions" :key="item[valueKey]" :value="item[valueKey]" |
||||
|
:label="item[labelKey]" class="flex-between"> |
||||
|
<span>{{ item.label }}</span> |
||||
|
<img v-if="item[valueKey] == selectedValue" src="@/assets/site/dropdown_chose_ic.svg" alt=""> |
||||
|
</el-option> |
||||
|
</div> |
||||
|
</el-select> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// import GuipInput from '@/components/GuipInput.vue'; |
||||
|
|
||||
|
export default { |
||||
|
name: 'SearchableSelect', |
||||
|
components: { |
||||
|
// GuipInput |
||||
|
}, |
||||
|
|
||||
|
props: { |
||||
|
// 双向绑定的值 |
||||
|
value: { |
||||
|
type: [String, Number, Array], |
||||
|
default: '' |
||||
|
}, |
||||
|
// 选项列表 |
||||
|
options: { |
||||
|
type: Array, |
||||
|
default: () => [] |
||||
|
}, |
||||
|
// 是否开启搜索功能 |
||||
|
searchable: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 是否可清空 |
||||
|
clearable: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
// 占位文本 |
||||
|
placeholder: { |
||||
|
type: String, |
||||
|
default: '请选择' |
||||
|
}, |
||||
|
// 搜索框占位文本 |
||||
|
searchPlaceholder: { |
||||
|
type: String, |
||||
|
default: '输入关键字搜索' |
||||
|
}, |
||||
|
// 选项的 label 字段名 |
||||
|
labelKey: { |
||||
|
type: String, |
||||
|
default: 'label' |
||||
|
}, |
||||
|
// 选项的 value 字段名 |
||||
|
valueKey: { |
||||
|
type: String, |
||||
|
default: 'value' |
||||
|
}, |
||||
|
// 自定义筛选方法 |
||||
|
filterMethod: { |
||||
|
type: Function, |
||||
|
default: null |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
selectedValue: this.value, |
||||
|
searchText: '', |
||||
|
filteredOptions: this.options |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
watch: { |
||||
|
value(newVal) { |
||||
|
console.log(this.selectedValue, 'selectedValue---'); |
||||
|
this.selectedValue = newVal |
||||
|
}, |
||||
|
|
||||
|
options(newOptions) { |
||||
|
this.filteredOptions = newOptions |
||||
|
// 如果搜索框有内容,重新筛选 |
||||
|
if (this.searchText) { |
||||
|
this.handleSearch(this.searchText) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
// 处理搜索输入 |
||||
|
handleSearch(keyword) { |
||||
|
console.log(keyword,'keyword---'); |
||||
|
if (this.filterMethod && typeof this.filterMethod === 'function') { |
||||
|
// 使用自定义筛选方法 |
||||
|
this.filteredOptions = this.filterMethod(keyword, this.options) |
||||
|
} else { |
||||
|
// 默认筛选方法 |
||||
|
if (!keyword) { |
||||
|
this.filteredOptions = this.options |
||||
|
} else { |
||||
|
const lowerKeyword = keyword.toLowerCase() |
||||
|
this.filteredOptions = this.options.filter(item => { |
||||
|
const label = item[this.labelKey] || '' |
||||
|
return label.toString().toLowerCase().includes(lowerKeyword) |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 处理选择变化 |
||||
|
handleChange(value) { |
||||
|
this.$emit('input', value) |
||||
|
this.$emit('change', value) |
||||
|
}, |
||||
|
|
||||
|
// 处理清空 |
||||
|
handleClear() { |
||||
|
this.searchText = '' |
||||
|
this.filteredOptions = this.options |
||||
|
this.$emit('clear') |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.optionsList{ |
||||
|
max-height: 230px; |
||||
|
overflow-y: auto; |
||||
|
} |
||||
|
.select-search-input { |
||||
|
padding: 6px 12px; |
||||
|
width: 206px; |
||||
|
margin-bottom: 12px; |
||||
|
outline: none; |
||||
|
border-color: transparent !important; |
||||
|
/* margin: 6px 12px; */ |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
::v-deep .el-input__inner:hover { |
||||
|
border-color: #006aff; |
||||
|
} |
||||
|
::v-deep .el-input__inner:focus { |
||||
|
border-color: #006aff; |
||||
|
} |
||||
|
.el-form-item{ |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-select-dropdown__list { |
||||
|
padding: 12px 0; |
||||
|
} |
||||
|
|
||||
|
::v-deep .el-input__inner { |
||||
|
padding: 6px 10px; |
||||
|
} |
||||
|
|
||||
|
.el-select-dropdown__item.selected { |
||||
|
font-weight: normal; |
||||
|
} |
||||
|
|
||||
|
.el-select-dropdown__item { |
||||
|
padding: 6px 10px; |
||||
|
border-radius: 2px; |
||||
|
color: #1E2226; |
||||
|
background: #FFFFFF; |
||||
|
margin: 0 12px; |
||||
|
|
||||
|
&:hover { |
||||
|
background: #F6F7FA; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -1,49 +0,0 @@ |
|||||
<template> |
|
||||
<div class="site-setting-wrap"> |
|
||||
|
|
||||
</div> |
|
||||
</template> |
|
||||
<script> |
|
||||
// import GuipInput from '@/components/GuipInput.vue'; |
|
||||
|
|
||||
export default { |
|
||||
// 站点设置 |
|
||||
name: '', |
|
||||
props: [''], |
|
||||
components: { |
|
||||
// GuipInput, |
|
||||
|
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
|
|
||||
} |
|
||||
}, |
|
||||
methods: { |
|
||||
onSwitchChange(data) { |
|
||||
console.log(data, '---'); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
<style lang="scss"> |
|
||||
.domain-wrap { |
|
||||
.domain-item{ |
|
||||
margin-bottom: 10px; |
|
||||
} |
|
||||
.domain-item p:last-child{ |
|
||||
padding-left: 23px; |
|
||||
color: #8A9099; |
|
||||
} |
|
||||
p{ |
|
||||
text-align: left; |
|
||||
line-height: 18px; |
|
||||
margin-bottom: 8px; |
|
||||
} |
|
||||
.domain-box { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
justify-content: flex-start; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
Loading…
Reference in new issue