自定义picker-view组件
1.示例
2.代码
<template><u-popupv-model="show"mode="bottom":safe-area-inset-bottom="true"mask-close-able@close="clickCancel"><view class="popup-con"><view class="title"><image :src="useImageUrl('', 'close')" alt="" class="close" @click="clickCancel" /><view class="title">{{ props.title == "paly" ? "种类" : "开奖期号" }}</view><view class="confirm" @click="clickDefine">确认</view></view><view class="picker-container"><picker-viewv-if="props.listData.length > 0"indicator-class="select-line"class="custom-picker":immediate-change="true"@change="handleChange":value="[currentIndex]"><picker-view-column><viewv-for="(item, index) in props.listData":key="index"class="picker-item":style="getItemStyle(index)"><text v-if="item.date">第{{ item.lable }}期-{{ formatDate(item.date) }}</text><text v-else>{{ item.lable }}</text></view></picker-view-column></picker-view></view></view></u-popup>
</template><script setup lang="ts">
import { ref, watch } from "vue";
import { useImageUrl } from "/@/cool/utils/comm";interface PickerItem {lable: string;date?: Date | string;
}
const props = defineProps({show: {type: Boolean,default: false,},title: {type: String,default: "",},listData: {type: Array as () => PickerItem[],default: () => [],},
});const show = ref(false);
const currentIndex = ref(0);
const selectedData = ref<any>(null);watch(() => props.show,(val) => {show.value = val;},
);const handleChange = (e:any) => {const val = e.detail.value[0];currentIndex.value = val;selectedData.value = props.listData[val];
};const getItemStyle = (index: number) => {const isActive = currentIndex.value === index;return {height: "94rpx",lineHeight: "94rpx",fontSize: isActive ? "36rpx" : "30rpx",fontWeight: isActive ? "500" : "400",color: isActive ? "#1D2129" : "#86909C",display: "flex",justifyContent: "center",alignItems: "center",};
};const formatDate = (dateStr: any) => {return dateStr ? dateStr.replace(/-/g, "/") : "";
};const emits = defineEmits(["confirm", "cancel"]);const clickDefine = () => {emits("confirm", selectedData.value);
};const clickCancel = () => {emits("cancel");
};
const updatedIndex = (e: number) => {currentIndex.value = e;
};
defineExpose({updatedIndex,
});
</script><style lang="scss" scoped>
.popup-con {padding: 32rpx 38rpx;
}
.title {display: flex;align-items: center;justify-content: space-between;position: relative;height: 50rpx;.close {width: 40rpx;height: 40rpx;position: absolute;}.title {color: #1d2129;text-align: center;font-family: "PingFang SC";font-size: 36rpx;font-style: normal;font-weight: 500;line-height: 50rpx;position: absolute;left: 50%;transform: translateX(-50%);}.confirm {color: #ff7d12;text-align: center;font-family: "PingFang SC";font-size: 32rpx;font-style: normal;font-weight: 500;line-height: 48rpx;position: absolute;right: 0;}
}
::v-deep .select-line {height: 94rpx;
}
::v-deep .select-line::after {border-bottom: 2rpx solid #fff;
}
::v-deep .select-line::before {border-top: 2rpx solid #fff;
}
.picker-container {width: 100%;height: 280rpx;background-color: #fff;overflow: hidden;margin-top: 20rpx;.custom-picker {width: 100%;height: 100%;.picker-item {height: 88rpx;text-align: center;transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);will-change: transform, font-size;}}
}
</style>