You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
6.0 KiB
209 lines
6.0 KiB
<template>
|
|
<view style="width: 100%; height: 100%">
|
|
<view class="select-mask" v-show="visible" @click="hideOption"></view>
|
|
<view class="select-section" :style="contentStyle" @click="showOption">
|
|
<text class="text" :class="label ? '' : 'placeholder'" :style="label ? '' : placeholderStyle">{{ label || placeholder }}</text>
|
|
<view class="icon"></view>
|
|
<view class="options-area" v-show="visible">
|
|
<slot>
|
|
<view class="option" v-for="item in options" :key="item.value" @click.stop="handleSelect(item)">
|
|
<text>{{ item.label }}</text>
|
|
<view v-show="isSelected(item.value)" class="icon"></view>
|
|
</view>
|
|
</slot>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
value: {
|
|
default: ''
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: '请选择'
|
|
},
|
|
/**
|
|
* 下拉框选项
|
|
* @param {Object} item
|
|
* @property {String} label - 选项名称
|
|
* @property {String} value - 选项值
|
|
*/
|
|
options: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
placeholderStyle: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
/**
|
|
* 指向select-section的样式
|
|
*/
|
|
contentStyle: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
/**
|
|
* 是否多选
|
|
*/
|
|
multiple: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
visible: false,
|
|
label: ''
|
|
}
|
|
},
|
|
methods: {
|
|
handleSelect(item) {
|
|
if (this.multiple) {
|
|
let value = []
|
|
if (!this.value) {
|
|
value = []
|
|
} else {
|
|
value = [...this.value]
|
|
}
|
|
const index = value.indexOf(item.value)
|
|
if (index > -1) {
|
|
value.splice(index, 1)
|
|
} else {
|
|
value.push(item.value)
|
|
}
|
|
this.$emit('input', value)
|
|
} else {
|
|
this.hideOption()
|
|
this.$emit('input', item.value)
|
|
}
|
|
},
|
|
showOption() {
|
|
this.visible = true
|
|
},
|
|
hideOption() {
|
|
this.visible = false
|
|
},
|
|
isSelected(value) {
|
|
if (this.multiple) {
|
|
return this.value.indexOf(value) > -1
|
|
} else {
|
|
return this.value === value
|
|
}
|
|
},
|
|
/**
|
|
* 处理外层val或options改变的情况
|
|
*/
|
|
handleChange(val, options) {
|
|
if (this.multiple) {
|
|
let labelList = []
|
|
for (let value of val) {
|
|
const item = options.find((item) => item.value === value)
|
|
if (item) {
|
|
labelList.push(item.label)
|
|
} else {
|
|
labelList.push(' ')
|
|
}
|
|
}
|
|
this.label = labelList.join(' , ')
|
|
} else {
|
|
let target = options.find((o) => o.value === val)
|
|
this.label = target?.label || ''
|
|
}
|
|
}
|
|
},
|
|
watch: {
|
|
value(val) {
|
|
this.handleChange(val, this.options)
|
|
},
|
|
options(val) {
|
|
this.handleChange(this.value, val)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.select-section {
|
|
width: 100%;
|
|
height: 100%;
|
|
// min-height: 64rpx;
|
|
position: relative;
|
|
// 将fixed元素锚定到该元素
|
|
transform: translateX(0);
|
|
// z-index: 300;
|
|
z-index: 90;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
color: rgb(51, 51, 51);
|
|
font-size: 28rpx;
|
|
line-height: 40rpx;
|
|
white-space: nowrap;
|
|
padding: 12rpx 24rpx;
|
|
background-color: rgb(245, 245, 245);
|
|
border-radius: 8rpx;
|
|
.text {
|
|
flex: 1 1 auto;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
.icon {
|
|
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAAgCAYAAABHA7voAAACtklEQVRYhdXYOW8TQRgG4CcxBHIQTA5uCCDRICSoKChB3MefBYmjpYCCDjokEnIQEDRIiPsqPltJjGe8a++G8EpWJPvLeB7P7OzsDGEIZ3AK27GEx/js/8oUzmMWH/EU80M4i3MdxR9wB582s4cDZB+uiwFan7sNXMBIxwc7cRQv8aP27g2WWYHrNEBj2N/qdpq4IbBbNTOij91wMNLAtJi/3TKKQ2Ikf1bevcEyJXA7MjXPG3iD45nCMVsP2cQt+dm1iCcNcY3N45g0chwHBPJXdf3sK7sFbjRTs4yH+NVovfEdC5iTRk5gv3+LnBS48UzNMh5ozbbGug++CWRuJHdhrxjxzUZOCNxEpmYDjo1AiiEnxeo1j999drZsxnFb/MCptKflhnWiE0gx5G6x+m4GckyM3GSmpo37657dDUgxZLP1WlAfclTgmpmaJI40kEC+EreQ1I10j/hlF3r1tI/sxM3Wd6SSxZEHsjaSOeSUuDZe9WirTHYI3HSmZkUPHL2BFENOi4VgsUB7vTIicDOZmhWxWvbcJxcBUgw5I6bVUsE2u2VEbJxnMzWFcRQHsnZNHpNG7hWb9+US7bazHdfEo08qpXCUA8JXvReefa12V0q0uw1XxXYwldI4ygMphtzf+rtasA9XxIY+ldf6wLUb7ydFkAfFruJNj++/jCOZmte4r88H736BFEMeEhv5t10+G8YlcXKQykA4BgMSyEWckD4ZOIwveLfuvWFcFAtWKgPjGBzI2kjmkEfFAdZ7cYp3oVWfSiU4qgFSDDknjvNO42SmrcpwxK9ZZZpiFzLW5/9XiqO6EWzni7gmj0uPZCqrKsZRPZA1ZG66dmYV99RwBlsHkHLI2nDUB6QYspZpuT51Agnkku4b9Pbe8nudHagbSCBfiOfFMfFU8gyPbJ2D5P83fwA+SqvvLFrSmAAAAABJRU5ErkJggg==')
|
|
no-repeat center center/cover;
|
|
width: 28rpx;
|
|
height: 16rpx;
|
|
margin-left: 16rpx;
|
|
}
|
|
}
|
|
.select-mask {
|
|
width: 750rpx;
|
|
height: 100vh;
|
|
background-color: transparent;
|
|
position: fixed;
|
|
z-index: 80;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
}
|
|
.options-area {
|
|
z-index: 400;
|
|
position: fixed;
|
|
top: 100%;
|
|
left: 0rpx;
|
|
right: 0rpx;
|
|
height: 184rpx;
|
|
border-radius: 6rpx;
|
|
border: 2rpx solid #f5f5f5;
|
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
|
|
background-color: #fff;
|
|
overflow-y: auto;
|
|
.option {
|
|
height: 60rpx;
|
|
line-height: 60rpx;
|
|
// max-width: 500rpx;
|
|
// overflow-x: hidden;
|
|
// text-overflow: ellipsis;
|
|
padding: 0 24rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
border-bottom: 1rpx solid #f5f5f5;
|
|
.icon {
|
|
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABa0lEQVRYhe2Tu0oDQRSG/zNYmNmnsDVlouJ7xIAgWIigWCiCZoPiFdyNCgGLgBDwhqCxt/ARMpvHSYLF7rHKhewk7iZxbeavBuYcvm+YcwATE5N/DiUBWSp+z/u+f8wsHhs3s1/9dzNJwAMENQikgWAZwFz/vUgCzsxpACDw02DNn32BBn6pXOskEYFBuCC+qjvWka526gLhl6OkXGkPq5+qQAhOuFWOPBjVExLI2s0zIpFDwBeqJGvjwgGUPVfu/9YX2gIikWPmNBPeFwrttXHgRLiLAtcLMJ93zkz8kj1sb8SBM1BRjtyNAtcK1F35IYB8r4KrmUJzOwocRPcNV+5EhWsFdBJEVMkWW3uj4ASqek5qKw58qIBOAoxyxm4VtHDiB+WmNuPCgQhruGi3VgKguw3EdAqBfG/a+dlzrfVx4JEEdBLdZsKrcmSkTZlIQCtBePMcuToJPJZAR8IHrgF8xp12ExMTk2H5ASlkxc57+JuCAAAAAElFTkSuQmCC')
|
|
no-repeat center center/cover;
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
}
|
|
}
|
|
}
|
|
.placeholder {
|
|
color: #ccc;
|
|
}
|
|
</style>
|