2025-06-04 11:18:40 +08:00

258 lines
5.4 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="g-picker">
<view class="g-picker-value" @click="showPicker">
<!-- <u-input v-model="value" disabled disabledColor="#fff" :inputAlign="inputAlign" :placeholder="placeholder" style="pointer-events: none">
</u-input> -->
<text class="_value" v-if="value">{{value}}</text>
<text class="_placeholder" v-else>{{placeholder}}</text>
<!-- <u-icon v-if="!disabled" name="arrow-right" color="#c0c4cc"></u-icon> -->
</view>
<van-popup v-model:show="show" round position="bottom" :style="{ height: '40%' }">
<view class="g-picker-con">
<view class="g-picker-operate">
<text @click="show = false">取消</text>
<van-field v-if="searchFlag" class="g-input" v-model="searchName" placeholder="请输入">
</van-field>
<text @click="confirm">确认</text>
</view>
<!-- <view class="g-picker-list"> -->
<scroll-view class="g-picker-list" scroll-y="true">
<view class="g-picker-item" v-for="(col, inx) in searchList" :key="inx"
@click="checkItem(col, inx)">
<view :class="['g-picker-item_label', col._check ? 'g-picker-item--actived' : '']"
:style="{color: col._check ? activedColor : '#333'}">{{ col[filter.label] }}</view>
<u-icon class="g-picker-item_icon" v-show="col._check" name="checkbox-mark"
:color="activedColor"></u-icon>
</view>
</scroll-view>
<!-- </view> -->
</view>
</van-popup>
</view>
</template>
<script>
export default {
model: {
prop: 'value',
event: 'change'
},
props: {
// picker组件绑定值默认 name 用,拼接
value: {
type: String,
default: ""
},
// 数据源
columns: {
type: Array,
default: () => {
return []
}
},
// 数据显示格式化
filter: {
type: Object,
default: () => {
return {
label: 'label',
value: 'value'
}
}
},
defaultList: {
type: Array,
default: () => {
return []
}
},
// 是否开启搜索
searchFlag: {
type: Boolean,
default: false
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 选中后颜色
activedColor: {
type: String,
default: "#000"
},
// 文本对齐方式
inputAlign: {
type: String,
default: "right"
},
// 默认提示
placeholder: {
type: String,
default: "请选择"
}
},
data() {
return {
show: false,
columnsList: [],
value_chx: [],
searchName: "",
}
},
watch: {
value: {
handler(n) {
if (n) this.reShow();
},
immediate: true
},
columns: {
handler(n) {
this.columnsList = n
if (n.length) {
for (let val of this.columnsList) {
this.$set(val, '_check', false)
}
}
},
immediate: true
},
},
computed: {
searchList() {
const resultList = this.columnsList.filter(item => this.searchName ? item[this.filter.label].includes(this.searchName) : true)
this.defaultList.forEach(item => {
const find = resultList.find(ele => ele[this.filter.value] == item);
if(find) {
find._check = true;
}
})
// console.log(resultList, 1111)
return resultList;
}
},
methods: {
showPicker() {
if (this.disabled) return
this.show = true
},
reShow() {
let data = this.value.split(",")
setTimeout(() => {
for (let val of this.columnsList) {
if (data.includes(val[this.filter.label])) val._check = true
}
}, 100)
},
checkItem(col, inx) {
col._check = !col._check
},
// close() {
// this.show = false
// this.$emit("close")
// },
confirm() {
let value = [],
label = []
this.value_chx = this.columns.filter(v => v._check)
for (let val of this.value_chx) {
value.push(val[this.filter.value])
label.push(val[this.filter.label])
}
this.show = false
this.$emit('confirm', this.value_chx, value, label)
this.$emit('change', label.join(","))
}
}
}
</script>
<style lang="scss" scoped>
.g-picker {
.g-picker-value {
display: flex;
}
.g-picker-con {
color: #333;
font-size: 28rpx;
.g-picker-operate {
display: flex;
align-items: center;
justify-content: space-between;
height: 80rpx;
padding: 0 32rpx;
position: relative;
.g-input {
width: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 11;
border: 1rpx solid;
padding: 0 32rpx !important;
border-color: #c1c1c1;
}
:deep(.van-field__control) {
font-size: 28rpx;
}
:deep(.van-field__control::placeholder) {
font-size: 28rpx;
}
text {
color: #999;
&:last-child {
color: #3c9cff;
}
}
}
.g-picker-list {
min-height: 30vh;
max-height: 60vh;
// overflow-y: scroll;
.g-picker-item {
position: relative;
width: 100%;
height: 80rpx;
.g-picker-item_label {
width: 66%;
margin: 0 auto;
text-align: center;
line-height: 80rpx;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.g-picker-item--actived {
font-weight: 600;
}
.g-picker-item_icon {
position: absolute;
top: 50%;
right: 40rpx;
transform: translateY(-50%);
}
}
}
}
}
._value {
word-break: break-all;
line-height: 36rpx;
}
._placeholder {
color: rgb(192, 196, 204);
font-size: 28rpx;
}
</style>