mall-app-t/peach/components/p-picker/p-picker.vue

173 lines
4.5 KiB
Vue

<template>
<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>
</template>
<script setup>
import { defineEmits, defineProps, ref, onMounted, computed, defineExpose } from 'vue'
const pickerViewValue = ref([])
const indicatorStyle = `height: 50px`
const props = defineProps({
// 传入pickerview列表 value label字段
optionsCols: {
default: () => [],
required: true,
type: Array,
},
mode: {
type: String,
default: 'single',
},
})
const childrenList = computed(() => {
return props.optionsCols[pickerViewValue.value[0]]?.children
})
// 暴露两个方法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) => {
pickerViewValue.value = defaultValue
pickerPopupRef.value.open('bottom')
}
/**
* @author: joey wong
* @description: 滚动改变事件
* @param {*} e
* @return {*}
*/
const bindChange = (e) => {
pickerViewValue.value = e.detail.value
if (props.mode === 'multiple') {
if (pickerViewValue.value[0] !== e.detail.value[0]) {
pickerViewValue.value[1] = 0
}
}
emit('change', {
value: pickerViewValue.value,
})
}
/**
* @author: joey wong
* @description: 关闭模态框事件
* @return {*}
*/
const onClosePopup = () => {
pickerPopupRef.value.close()
}
/**
* @author: joey wong
* @description: 确认事件
* @return {*}
*/
const onConfirmPopup = () => {
emit('confirm', {
value: pickerViewValue.value,
})
onClosePopup()
}
defineExpose({
onOpen,
})
</script>
<style lang="scss" scoped>
.custom-picker {
display: flex;
align-items: center;
&-text {
margin-right: 5.7rpx;
}
&-icon {
width: 19rpx;
height: 12rpx;
margin-bottom: 3rpx;
}
.popup-content {
height: 500rpx;
.item {
text-align: center;
line-height: 50px;
}
}
.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;
}
}
</style>