简单说一下功能点
微信小程序设置用户的生日,直接使用日历有些不太友好,所以选择手搓一个类似某音和某红书差不多的样式。
在实现该功能还是有一些小的注意点的,最主要的就是-->日期选择需要3级联动,因为要获取当前年份有多少月份、以及当前年份的月份有多少天。总不能今天是2023年12月3号,但滑动选项里面有明天甚至以后的日期吧。
使用的是VantWeapp组件实现的滑动效果,当然,使用其他组件的一样,结尾附源代码。
功能样式图
日期选择默认的打开样式
在选择最新日期时候
除了选择天数不会去重新拉取日期外,当滑动触发年和月的改变,都需要去拉取最新的日期。若拉取的日期的天数或月份不够上一次选择的时候,默认会选择最后一个日期等等小细节吧。
主要代码功能
自己封装的一个时间工具
/**
* 获取有多少年份[默认截至1949]
* @param actYear 截至到多少年份
* @returns 年份数组
*/
export const getYear = (actYear?: number): Array<number> => {
actYear = actYear || 1949;
const date = new Date();
if (actYear >= date.getFullYear()) return [1949];
let yearArr = [];
for (let i = actYear; i <= date.getFullYear(); i++) yearArr.push(i);
return yearArr;
};
/**
* 获取当前年份有多少月份
* @param year 年份
* @returns 月份数组
*/
export const getMonthToYear = (year: number): Array<number> => {
const date = new Date();
const nowYear = date.getFullYear();
if (year > nowYear) return [1];
let monthArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
if (year == nowYear) {
monthArr = [];
for (let i = 1; i <= date.getMonth() + 1; i++) monthArr.push(i);
}
return monthArr;
};
/**
* 获取当前年的月份有多少天
* @param year 年份
* @param month 月份
* @returns 天数数组
*/
export const getDayToMoYe = (year: number, month: number): Array<number> => {
const date = new Date();
const nowYear = date.getFullYear();
const nowMonth = date.getMonth() + 1;
if (year > nowYear) return [1];
let monthArr = getMonthToYear(year);
if (month > monthArr.length) return [1];
let dayArr = [];
if (year == nowYear && month == nowMonth) {
for (let i = 1; i <= date.getDate(); i++) dayArr.push(i);
return dayArr;
}
for (let i = 1; i <= new Date(year, month, 0).getDate(); i++) dayArr.push(i);
return dayArr;
};
组件代码
特别说明:手动删掉了不重要的代码,请勿直接复制
<template>
<van-popup
class="pd-10"
:show="showDateChoose"
round
position="bottom"
@close="showDateChoose = false">
<view class="mt-10 flex-center-zy pd-zy-15">
<view class="ft-color-hui" @click="showDateChoose = false">取消</view>
<view>选择你的生日</view>
<view class="ft-big-4 ft-color-red" @click="saveDate">保存</view>
</view>
<van-picker
:columns="initDate"
@change="onDateChange"
:visible-item-count="3"
:loading="dateLoding" />
</van-popup>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive } from 'vue';
import FixVue from '@/common/pages/fix_vue/FixVue';
import { getYear, getMonthToYear, getDayToMoYe } from '@/utils/TimeUtil';
//展示日期选择框和日期加载
let showDateChoose = ref(false);
let dateLoding = ref(true);
//打开日期选择
const openDate = () => {
dateLoding.value = true;
showDateChoose.value = true;
//测试数据,后需要修改为动态获取的用户生日,若用户生日没有则给默认值
initDateMethod('2001-5-10');
dateLoding.value = false;
};
//保存日期
let newDate = ref('');
const saveDate = () => {
if (!newDate.value) return;
//与原本日期进行对比若不同,调用修改生日的接口。。。
};
//选择新时间
const onDateChange = (e: any) => {
const { picker, index } = e.detail;
if (index == 2) return (newDate.value = picker.getValues());
const upDate = picker.getIndexes();
const year = initDate.value[0].values[upDate[0]];
const month = initDate.value[1].values[upDate[1]];
const day = initDate.value[2].values[upDate[2]];
initDate.value = [];
const result = initDateMethod(year + '-' + month + '-' + day);
newDate.value = picker.getValues();
setTimeout(() => {
picker.setColumnIndex(0, result[0]);
picker.setColumnIndex(1, result[1]);
picker.setColumnIndex(2, result[2]);
}, 10);
};
//初始化年份
let initDate = ref([]);
const initDateMethod = (date: string) => {
let dateSplit = date.split('-');
const year = getYear();
const month = getMonthToYear(+dateSplit[0]);
const day = getDayToMoYe(+dateSplit[0], +dateSplit[1]);
let yearIndex = year.indexOf(+dateSplit[0]) == -1 ? year.length - 1 : year.indexOf(+dateSplit[0]);
initDate.value.push({
values: year,
defaultIndex: yearIndex
});
let monthIndex =
month.indexOf(+dateSplit[1]) == -1 ? month.length - 1 : month.indexOf(+dateSplit[1]);
initDate.value.push({
values: month,
defaultIndex: monthIndex
});
let dayIndex = day.indexOf(+dateSplit[2]) == -1 ? day.length - 1 : day.indexOf(+dateSplit[2]);
initDate.value.push({
values: day,
defaultIndex: dayIndex
});
return [yearIndex, monthIndex, dayIndex];
};
</script>
//主要的css样式,主要添加日期后面的一些提示字,如年、月、日
<style lang="less" scoped>
::v-deep.van-picker-column__item--selected {
color: black;
}
::v-deep[data-index='0'] {
.van-picker-column__item--selected::after {
content: ' 年';
}
}
::v-deep[data-index='1'] {
.van-picker-column__item--selected::after {
content: ' 月';
}
}
::v-deep[data-index='2'] {
.van-picker-column__item--selected::after {
content: ' 日';
}
}
::v-deep.van-picker {
height: 150px !important;
margin-top: 20px;
}
</style>
结束语
至此功能就完结了,接下来已编写完成仿某信的聊天样式,如自动根据输入框弹起高度修改聊天内容触底,以及动态调整输入框的高度和最大限制等等。若有需求的小伙伴,可以聊聊,我会分享个人的想法以及做法,若需求大会写一篇文章以及源码分享。
来源:juejin.cn/post/7307587537295851535