fourPayProject/51pay-uni/components/ep-select/ep-select.vue
2025-03-31 10:14:11 +08:00

297 lines
5.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="ep-select-box">
<!-- 蒙版区域 开始 -->
<view class="ep-mask-box" v-show="show_option" @click="clickMask"></view>
<!-- 蒙版区域 开始 -->
<!-- 输入框区域 开始 -->
<view class="ep-input-box" :class="{'disabled':disabled}" @click="openOptions">
<!-- 文本模式 -->
<view v-if="!filterable" class="label-item">{{showLabel}}</view>
<!-- 输入框模式 -->
<view v-else class="input-item">
<uni-easyinput type="text" v-model="input" :placeholder="showLabel" :placeholderStyle="placeholderStyle"
:clearable="false" :inputBorder="false"></uni-easyinput>
</view>
<!-- 箭头图标切换 -->
<text v-if="!show_option" class="iconfont icon-xiala"></text>
<text v-else class="iconfont icon-xialashang"></text>
</view>
<!-- 输入框区域 结束 -->
<!-- 弹出的下拉区域 开始 -->
<view v-show="show_option" class="ep-select-content-wrap">
<scroll-view class="ep-select-content" :scroll-y="true">
<view v-for="item in filterOptions" :key="item[value_key]"
:class="{'disabled':item.disabled,'active':value==item[value_key]}" class="option-item"
@click="itemClick(item)">{{item[label_key]}}</view>
<view v-if='filterOptions.length==0' class="empty-text">暂无数据</view>
</scroll-view>
<text class="triangle"></text>
</view>
<!-- 弹出的下拉区域 结束 -->
</view>
</template>
<script>
export default {
data() {
return {
show_option: false, //是否展示下拉选项
input: "", //开启搜索时输入框的值
}
},
props: {
value: {
type: [String, Number],
default: ""
},
options: {
type: Array,
default: function() {
return []
}
},
value_key: {
type: String,
default: "value"
},
label_key: {
type: String,
default: "label"
},
disabled: {
type: Boolean,
default: false
},
filterable: {
type: Boolean,
default: false
},
"keep-input": {
type: Boolean,
default: false
},
},
model: {
prop: 'value',
event: "input"
},
mounted() {
},
methods: {
//点击选中选项
itemClick(item) {
if (item.disabled) return
//关闭
this.show_option = false
//修改v-model的值
this.$emit('input', item[this.value_key])
//将事件通知父组件
this.$emit('change', item)
//重置输入框
if (!this.keepInput) {
this.input = ''
}
},
//展开选项
openOptions() {
//禁用则不做任何操作
if (this.disabled) return
//模式判断 select or picker
console.log(this.mode)
this.show_option = true
},
//点击蒙版
clickMask() {
//关闭下拉选项
this.show_option = false
//重置输入框
if (!this.keepInput) {
this.input = ''
}
}
},
computed: {
//输入框要展示的文本 动态计算placeholder
showLabel() {
console.log(this.options, "this.options")
//根据v-model传入的值查找对应的下拉项
var target = this.options.find(item => {
return item[this.value_key] == this.value
})
//如果目标项存在 则返回其 label
if (target) {
return target[this.label_key]
} else {
return "请选择"
}
},
//动态计算placeholder的样式
placeholderStyle() {
//如果未选中 则灰色
if (!this.value) {
return 'color:#999;'
} else if (this.show_option) {
//如果已选中 但是下拉框已弹出 则灰色
return 'color:#999;'
} else {
//否则黑色
return 'color:#333;'
}
},
//过滤后的列表
filterOptions() {
return this.options.filter(item => {
return item[this.label_key].includes(this.input)
})
},
}
}
</script>
<style scoped lang="scss">
/* 引入字体图标 */
@import './iconfont.css';
.ep-select-box {
box-sizing: border-box;
position: relative;
width: 100px;
color: #333;
background-color: #fff;
font-size: 14px;
.ep-mask-box {
position: fixed;
z-index: 999;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: none;
}
.ep-input-box {
border: 1px solid rgb(229, 229, 229);
border-radius: 4px;
/* padding-left:10px; */
position: relative;
cursor: pointer;
display: flex;
align-items: center;
.label-item {
width: 50px;
display: flex;
align-items: center;
height: 36px;
padding-left: 10px;
}
.input-item {
display: flex;
align-items: center;
min-height: 36px;
}
.iconfont {
position: absolute;
top: 50%;
right: 5px;
font-size: 20px;
transform: translateY(-50%);
color: #B8B8B8;
}
}
.disabled {
cursor: not-allowed;
background-color: #f5f7fa;
.label-item {
color: #999;
}
}
.ep-select-content-wrap {
width: 100%;
position: absolute;
top: 45px;
left: 0;
z-index: 9999;
padding-top: 6px;
.ep-select-content {
background-color: #fff;
padding: 3px 0;
font-size: 14px;
box-shadow: 0 0 20px 5px rgba(0, 0, 0, 0.3);
border-radius: 5px;
max-height: 181px;
.option-item {
padding: 8px 18px;
cursor: pointer;
&:hover {
background-color: #f5f7fa;
}
}
.active {
color: #007AFF;
}
.disabled {
color: #c0c4cc;
&:hover {
background-color: #f5f7fa;
}
}
}
.triangle {
width: 0;
height: 0;
border-top: 6px solid rgba(0, 0, 0, 0);
border-right: 6px solid rgba(0, 0, 0, 0);
border-bottom: 6px solid #fff;
border-left: 6px solid rgba(0, 0, 0, 0);
position: absolute;
top: -6px;
left: 50%;
transform: translateX(-50%);
box-sizing: content-box;
}
}
}
.empty-text {
color: #999;
text-align: center;
padding: 3px 0;
font-size: 14px;
}
.uni-easyinput__placeholder-class {
font-size: 14px !important;
font-weight: 400 !important;
height: 100%;
display: flex;
align-items: center;
}
</style>