176 lines
4.4 KiB
Vue
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>
|