2025-07-11 17:43:34 +08:00

176 lines
4.4 KiB
Vue

<template>
<view class="picker_box">
<uni-popup ref="popupRef" :is-mask-click="false" animation type="bottom">
<view class="popup_box">
<view v-if="title" class="header_title">
{{ title }}
</view>
<picker-view
:indicator-style="indicatorStyle"
:overshoot="false"
:value="pickValue"
class="picker-view"
@change="bindChange"
>
<picker-view-column>
<view
v-for="(item, index) in pickList"
:key="index"
:class="['picker_item', pickValue[0] === index ? 'selected_item' : '']"
>{{ item.name }}</view
>
</picker-view-column>
</picker-view>
<view class="operation">
<button class="cancel_btn" @tap="tapCancelBtn">取消</button>
<button class="confirm_btn" @tap="tapConfirmBtn">确定</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { computed, nextTick, ref, watch } from 'vue';
const props = defineProps({
title: {
type: String,
default: '',
},
modelValue: {
type: Boolean,
default: false,
},
pickList: {
type: Array,
default: () => [],
},
pickVal: {
type: Array,
},
});
const emits = defineEmits(['update:modelValue', 'confirm']);
const btnDisabled = ref(true); // 按钮禁用
const popupRef = ref(null);
const indicatorStyle = ref(`height: 50px;`);
const pickValue = ref([]);
const isBindChange = ref(false); // 是否触发选择操作
// 选择值
function bindChange(e) {
isBindChange.value = true;
btnDisabled.value = false;
pickValue.value = e.detail.value;
}
// 取消
function tapCancelBtn() {
emits('update:modelValue', false);
}
// 确定
function tapConfirmBtn() {
setTimeout(() => {
if (isBindChange.value) {
// 选择
if (!btnDisabled.value) {
emits('confirm', pickValue.value);
}
} else {
// 没有选择
emits('confirm', pickValue.value);
}
}, 620);
}
watch(
() => props.modelValue,
() => {
if (props.modelValue) {
nextTick(() => {
popupRef.value.open();
pickValue.value = props.pickVal;
btnDisabled.value = true;
isBindChange.value = false;
});
} else {
if (popupRef.value) {
popupRef.value.close();
isBindChange.value = false;
btnDisabled.value = true;
}
}
},
{
immediate: true,
deep: true,
},
);
</script>
<style lang="scss" scoped>
.picker_box {
.popup_box {
position: relative;
height: 660rpx;
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
overflow: hidden;
padding: 50rpx 0 0 0;
.header_title {
position: absolute;
top: 30rpx;
left: 30rpx;
z-index: 99;
color: #333;
font-size: 32rpx;
}
.picker-view {
width: 750rpx;
height: 450rpx;
margin: 20rpx 0 20rpx 0;
}
.picker_item {
line-height: 100rpx;
text-align: center;
}
.selected_item {
color: #615dff;
}
.operation {
display: flex;
justify-content: center;
position: fixed;
width: 100%;
padding-top: 16rpx;
border-top: 1px solid #eeeeee;
bottom: 60rpx;
button::after {
border: none;
}
.cancel_btn {
width: 230rpx;
height: 90rpx;
color: #615dff;
background-color: #ececff;
}
.confirm_btn {
margin-left: 20rpx;
height: 90rpx;
width: 440rpx;
color: #fff;
background-color: #615dff;
}
}
}
}
</style>