2024-06-04 18:43:13 +08:00
|
|
|
|
<template>
|
2024-06-11 00:34:43 +08:00
|
|
|
|
<view class="custom-picker">
|
|
|
|
|
<!-- 普通弹窗 -->
|
|
|
|
|
<uni-popup type="bottom" ref="pickerPopupRef" background-color="#fff">
|
|
|
|
|
<view class="popup-header">
|
|
|
|
|
<view class="button-cancel" @click="onClosePopup">取消</view>
|
|
|
|
|
<view class="button-link" @click="onConfirmPopup">确定</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="popup-content">
|
|
|
|
|
<picker-view :indicator-style="indicatorStyle" :value="pickerViewValue" @change="bindChange"
|
|
|
|
|
class="picker-view">
|
|
|
|
|
<template v-if="mode === 'single'">
|
|
|
|
|
<picker-view-column>
|
|
|
|
|
<view class="item" v-for="(item, index) in props.optionsCols" :key="`${item.value}-${index}`">{{
|
|
|
|
|
item.label ?? item.name }}</view>
|
|
|
|
|
</picker-view-column>
|
|
|
|
|
</template>
|
|
|
|
|
<template v-else>
|
|
|
|
|
<picker-view-column>
|
|
|
|
|
<view class="item" v-for="(item, index) in props.optionsCols" :key="`${item.value}-${index}`">{{ item.name
|
|
|
|
|
}}</view>
|
|
|
|
|
</picker-view-column>
|
|
|
|
|
<picker-view-column>
|
|
|
|
|
<view class="item" v-for="(item, index) in childrenList" :key="`${item.value}-${index}`">{{
|
|
|
|
|
item.name
|
|
|
|
|
}}</view>
|
|
|
|
|
</picker-view-column>
|
|
|
|
|
</template>
|
|
|
|
|
</picker-view>
|
|
|
|
|
</view>
|
|
|
|
|
</uni-popup>
|
|
|
|
|
</view>
|
2024-06-04 18:43:13 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { defineEmits, defineProps, ref, onMounted, computed, defineExpose } from 'vue'
|
|
|
|
|
const pickerViewValue = ref([])
|
|
|
|
|
const indicatorStyle = `height: 50px`
|
|
|
|
|
const props = defineProps({
|
2024-06-11 00:34:43 +08:00
|
|
|
|
// 传入pickerview列表 value label字段
|
|
|
|
|
optionsCols: {
|
|
|
|
|
default: () => [],
|
|
|
|
|
required: true,
|
|
|
|
|
type: Array,
|
|
|
|
|
},
|
|
|
|
|
mode: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: 'single',
|
|
|
|
|
},
|
2024-06-04 18:43:13 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const childrenList = computed(() => {
|
2024-06-11 00:34:43 +08:00
|
|
|
|
return props.optionsCols[pickerViewValue.value[0]]?.children
|
2024-06-04 18:43:13 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 暴露两个方法confirm change
|
|
|
|
|
const emit = defineEmits(['confirm', 'change'])
|
|
|
|
|
// 弹窗ref
|
|
|
|
|
const pickerPopupRef = ref(null)
|
|
|
|
|
/**
|
|
|
|
|
* @author: joey wong
|
|
|
|
|
* @description: 打开弹窗
|
|
|
|
|
* @param {Array} defaultValue 默认选中index的值,如:[0,1]
|
|
|
|
|
* @return {*}
|
|
|
|
|
*/
|
|
|
|
|
const onOpen = (defaultValue) => {
|
2024-06-11 00:34:43 +08:00
|
|
|
|
pickerViewValue.value = defaultValue
|
|
|
|
|
pickerPopupRef.value.open('bottom')
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @author: joey wong
|
|
|
|
|
* @description: 滚动改变事件
|
|
|
|
|
* @param {*} e
|
|
|
|
|
* @return {*}
|
|
|
|
|
*/
|
|
|
|
|
const bindChange = (e) => {
|
2024-06-11 00:34:43 +08:00
|
|
|
|
pickerViewValue.value = e.detail.value
|
2024-06-04 18:43:13 +08:00
|
|
|
|
|
2024-06-11 00:34:43 +08:00
|
|
|
|
if (props.mode === 'multiple') {
|
|
|
|
|
if (pickerViewValue.value[0] !== e.detail.value[0]) {
|
|
|
|
|
pickerViewValue.value[1] = 0
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
2024-06-11 00:34:43 +08:00
|
|
|
|
}
|
2024-06-04 18:43:13 +08:00
|
|
|
|
|
2024-06-11 00:34:43 +08:00
|
|
|
|
emit('change', {
|
|
|
|
|
value: pickerViewValue.value,
|
|
|
|
|
})
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @author: joey wong
|
|
|
|
|
* @description: 关闭模态框事件
|
|
|
|
|
* @return {*}
|
|
|
|
|
*/
|
|
|
|
|
const onClosePopup = () => {
|
2024-06-11 00:34:43 +08:00
|
|
|
|
pickerPopupRef.value.close()
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @author: joey wong
|
|
|
|
|
* @description: 确认事件
|
|
|
|
|
* @return {*}
|
|
|
|
|
*/
|
|
|
|
|
const onConfirmPopup = () => {
|
2024-06-11 00:34:43 +08:00
|
|
|
|
emit('confirm', {
|
|
|
|
|
value: pickerViewValue.value,
|
|
|
|
|
})
|
|
|
|
|
onClosePopup()
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
|
|
|
|
defineExpose({
|
2024-06-11 00:34:43 +08:00
|
|
|
|
onOpen,
|
2024-06-04 18:43:13 +08:00
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.custom-picker {
|
2024-06-11 00:34:43 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
2024-06-04 18:43:13 +08:00
|
|
|
|
|
2024-06-11 00:34:43 +08:00
|
|
|
|
&-text {
|
|
|
|
|
margin-right: 5.7rpx;
|
|
|
|
|
}
|
2024-06-04 18:43:13 +08:00
|
|
|
|
|
2024-06-11 00:34:43 +08:00
|
|
|
|
&-icon {
|
|
|
|
|
width: 19rpx;
|
|
|
|
|
height: 12rpx;
|
|
|
|
|
margin-bottom: 3rpx;
|
|
|
|
|
}
|
2024-06-04 18:43:13 +08:00
|
|
|
|
|
2024-06-11 00:34:43 +08:00
|
|
|
|
.popup-content {
|
|
|
|
|
height: 500rpx;
|
|
|
|
|
|
|
|
|
|
.item {
|
|
|
|
|
text-align: center;
|
|
|
|
|
line-height: 34px;
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
2024-06-11 00:34:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.picker-view {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.button-link {
|
|
|
|
|
color: #1892ea;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.button-cancel {
|
|
|
|
|
color: #888;
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.popup-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
padding: 24rpx 38rpx 0;
|
|
|
|
|
}
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
|
|
|
|
</style>
|