按月筛选:
基于ui组件 vk-uview-ui 修改 地址:vkuviewdoc.fsq.pub/components/…
u-popup 组件可自行修改其他组件
<!--
* @Author: hht 13598360631@163.com
* @Date: 2023-01-03 16:57:09
* @LastEditors: hht 13598360631@163.com
* @LastEditTime: 2023-01-04 10:47:16
* @FilePath: ''
* @Description: '年月选择器'
-->
<template>
<u-popup
:maskCloseAble="maskCloseAble"
v-model="myVisible"
mode="bottom"
@close="close"
length="auto">
<view class="u-picker-header" @touchmove.stop.prevent="">
<view
class="u-btn-picker u-btn-picker--tips"
:style="{ color: cancelColor }"
hover-class="u-opacity"
:hover-stay-time="150"
@click="close('cancel')"
>
{{ cancelText }}
</view>
<view class="u-picker__title">{{ title }}</view>
<view
class="u-btn-picker u-btn-picker--primary"
:style="{ color: moving ? cancelColor : confirmColor }"
hover-class="u-opacity"
:hover-stay-time="150"
@touchmove.stop=""
@click.stop="getResult('confirm')"
>
{{ confirmText }}
</view>
</view>
<view class="u-picker-body">
<picker-view class="u-picker-view" :value="data.valueArr" @change="bindChange">
<picker-view-column>
<view class="item" v-for="(item,index) in data.years" :key="index">{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in data.months" :key="index">{{item}}月</view>
</picker-view-column>
</picker-view>
</view>
</u-popup>
</template>
<script setup >
import { reactive, getCurrentInstance,nextTick ,computed} from 'vue';
import { onUnload, onLoad, onReady } from '@dcloudio/uni-app'
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
// 是否允许通过点击遮罩关闭Picker
maskCloseAble: {
type: Boolean,
default: true
},
// 遮罩的模糊度
blur: {
type: [String, Number],
default: 0
},
// 取消按钮的文字
cancelText: {
type: String,
default: "取消"
},
// 确认按钮的文字
confirmText: {
type: String,
default: "确认"
},
// "取消"按钮的颜色
cancelColor: {
type: String,
default: "#606266"
},
// "确定"按钮的颜色
confirmColor: {
type: String,
default: "#2979ff"
},
// 年份开始时间
startYear: {
type: [String, Number],
default: 2021
},
// 年份结束时间
endYear: {
type: [String, Number],
default: 2050
},
// 默认显示的时间,2025-07-02
defaultTime: {
type: String,
default: ""
},
})
const data = reactive({
visible: false,
years: [],
year: '',
months: [],
month: '',
valueArr: [],
})
const emit = defineEmits(['update:modelValue','confirm'])
let myVisible = computed({
get: function() {
return props.modelValue
},
set: function(val) {
emit('update:modelValue', val)
}
})
onLoad(()=>{
init()
})
//日期时间处理
function initTimeValue() {
// 格式化时间,在IE浏览器(uni不存在此情况),无法识别日期间的"-"间隔符号
let fdate = props.defaultTime.replace(/\-/g, "/");
fdate = fdate && fdate.indexOf("/") == -1 ? `2022/01/01 ${fdate}` : fdate;
let time = null;
if (fdate) time = new Date(fdate);
else time = new Date();
// 获取年日月时分秒
data.years = []
data.months = []
data.year = time.getFullYear();
data.month = Number(time.getMonth()) + 1;
for (let i = 2020; i <= time.getFullYear(); i++) {
data.years.push(i)
}
for (let i = 1; i <= 12; i++) {
data.months.push(i)
}
}
function init() {
data.valueArr = [];
data.time = props.defaultTime
initTimeValue()
data.valueArr.push(0);
setYears();
data.valueArr.push(0);
setMonths();
}
function setYears() {
// 获取年份集合
data.years = generateArray(props.startYear, props.endYear);
// 设置this.valueArr某一项的值,是为了让picker预选中某一个值
data.valueArr.splice(data.valueArr.length - 1, 1, getIndex(data.years, data.year));
console.log(data.valueArr,'this.valueArr');
}
function setMonths() {
data.months = generateArray(1, 12);
data.valueArr.splice(data.valueArr.length - 1, 1, getIndex(data.months, data.month));
}
// 生成递进的数组
function generateArray(start, end) {
// 转为数值格式,否则用户给end-year等传递字符串值时,下面的end+1会导致字符串拼接,而不是相加
start = Number(start);
end = Number(end);
end = end > start ? end : start;
// 生成数组,获取其中的索引,并剪出来
return [...Array(end + 1).keys()].slice(start);
}
function getIndex (arr, val) {
let index = arr.indexOf(val);
// 如果index为-1(即找不到index值),~(-1)=-(-1)-1=0,导致条件不成立
return ~index ? index : 0;
}
function bindChange(e) {
const val = e.detail.value
data.year = formatNumber(data.years[val[0]])
data.month =formatNumber(data.months[val[1]])
data.time = `${data.year}-${data.month}`
}
// 小于10前面补0,用于月份,日期,时分秒等
function formatNumber(num) {
return +num < 10 ? "0" + num : String(num);
}
function getResult() {
emit('confirm', data.time)
close()
}
function close() {
myVisible.value = false
}
</script>
<style scoped>
.u-picker-view {
height: 100%;
box-sizing: border-box;
}
.item {
line-height: 100rpx;
text-align: center;
}
.u-picker-header {
width: 100%;
height: 2.8125rem;
padding: 0 1.25rem;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
font-size: 0.9375rem;
background: #fff;
position: relative;
}
.u-picker-header::after {
content: "";
position: absolute;
border-bottom: 1rpx solid #eaeef1;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
bottom: 0;
right: 0;
left: 0;
}
.u-picker-body {
width: 100%;
height: 500rpx;
overflow: hidden;
background-color: #fff;
}
</style>