123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- <template>
- <div :class="ui" class="hc-date-calendar-box">
- <div class="hc-date-picker-box">
- <div class="hc-date-picker">
- <el-date-picker class="block" v-model="toPicker" type="month" size="large" @change="datePickerChange"/>
- </div>
- <div class="hc-date-btn-box">
- <div class="hc-div-btn" @click="prevMonthClick">
- <HcIcon name="arrow-left"/>
- </div>
- <div class="hc-div-btn" @click="nextMonthClick">
- <HcIcon name="arrow-right"/>
- </div>
- </div>
- </div>
- <div class="hc-date-weekdays">
- <template v-for="item in weekdays" :key="item">
- <div class="hc-date-weekdays-day">{{item}}</div>
- </template>
- </div>
- <div class="hc-date-dates">
- <template v-for="item in datesDay">
- <div class="hc-date-dates-day" :class="item.type" @click="datesDayClick(item)">{{item.key}}</div>
- </template>
- </div>
- </div>
- </template>
- <script setup>
- import {nextTick, watch, ref} from "vue";
- import dayjs from "dayjs"
- import 'dayjs/locale/zh-cn'
- import {getObjNullValue} from "vue-utils-plus";
- dayjs.locale('zh-cn')
- const props = defineProps({
- ui: {
- type: String,
- default: ''
- },
- recordDate: {
- type: Object,
- default: () => ({})
- },
- dateData: {
- type: Array,
- default: () => ([])
- },
- })
- //变量
- const weekdays = ['日', '一', '二', '三', '四', '五', '六'] //星期头
- const toDays = ref({year: '', month: '', date: '', obj: {}})
- const selectedDate = ref({year: '', month: ''}) //选择年月的日期
- const toPicker = ref('') //年月下拉框
- const selectedDatas = ref(props.dateData)
- const choiceDate = ref({year: '', month: '', date: ''}) //选择的日期,年月日
- const curDateData = ref([]) //设置的日期
- const datesDay = ref([]) //日期数据
- //事件
- const emit = defineEmits(['choice-date'])
- //监听
- watch(() => [
- props.dateData,
- props.recordDate,
- ], ([dateData,recordDate]) => {
- selectedDatas.value = dateData
- setCurDateData(dateData, recordDate)
- })
- //渲染完成
- nextTick(()=> {
- const toDayJs = dayjs();
- toDays.value = {
- year: toDayJs.get('year'),
- month: toDayJs.get('month') + 1,
- date: toDayJs.get('date'),
- obj: toDayJs
- }
- selectedDate.value = {
- year: toDayJs.get('year'),
- month: toDayJs.get('month') + 1
- }
- choiceDate.value = {
- year: toDayJs.get('year'),
- month: toDayJs.get('month') + 1,
- date: toDayJs.get('date')
- }
- toPicker.value = toDayJs.format('YYYY-MM')
- emit('choice-date', isDayDateFormat(toDays.value))
- setCurDateData(props.dateData, props.recordDate)
- })
- //处理设置的日期
- const setCurDateData = (dateData, recordDate) => {
- let curData = [];
- for (let i = 0; i < dateData.length; i++) {
- let toDate = dayjs(dateData[i]).format("YYYY-MM-DD");
- const toDayJs = dayjs(toDate);
- curData.push({
- year: toDayJs.get('year'),
- month: toDayJs.get('month') +1,
- date: toDayJs.get('date')
- })
- }
- curDateData.value = curData;
- //判断是否选择了日期
- if (getObjNullValue(recordDate)) {
- getDatesDay(recordDate.year, recordDate.month)
- } else {
- getDatesDay()
- }
- }
- //获取日期
- const getDatesDay = (year, month) => {
- if (year && month) {
- let toDate = dayjs(year + '-' + month).format("YYYY-MM-DD"); //格式化一下先
- let days = dayjs(toDate).daysInMonth(); //天数
- let monthOneDay = dayjs(toDate).startOf("month").format("YYYY-MM-DD"); //获取当月第一天
- let weekday = dayjs(monthOneDay, "YYYY-MM-DD").day(); //获取当月第一天是星期几
- toPicker.value = dayjs(year + '-' + month).format('YYYY-MM');
- setDatesDay(days,weekday)
- } else {
- const toDayJs = toDays.value?.obj ?? {};
- let days = toDayJs.daysInMonth(); //天数
- let monthOneDay = toDayJs.startOf("month").format("YYYY-MM-DD"); //获取当月第一天
- let weekday = dayjs(monthOneDay, "YYYY-MM-DD").day(); //获取当月第一天是星期几
- toPicker.value = toDayJs.format('YYYY-MM');
- setDatesDay(days,weekday)
- }
- }
- //设置日期
- const setDatesDay = (days,weekday) => {
- let datesDayData = [];
- const selected = selectedDate.value; //选择的日期
- const choiceData = choiceDate.value; //选择的日期
- const dayData = toDays.value; //今天日期
- //添加头部
- for (let i = 0; i < weekday; i++) {
- datesDayData.push({type: 'excluded', key: '-'})
- }
- //处理日期
- for (let i = 0; i < days; i++) {
- let day = i + 1, type = '';
- type = setCurDate(selected,day)
- if (selected.year === dayData.year && selected.month === dayData.month && dayData.date === day) {
- type += ' selected'
- }
- if (choiceData.year === selected.year && choiceData.month === selected.month && choiceData.date === day) {
- type += ' choice'
- }
- datesDayData.push({type: type, key: day})
- }
- //添加尾数
- let lastNum = 42 - (weekday + days);
- for (let i = 0; i < lastNum; i++) {
- datesDayData.push({type: 'excluded', key: '-'})
- }
- datesDay.value = datesDayData;
- }
- const setCurDate = (selected,day) => {
- const curDate = curDateData.value; //设置的日期
- for (let x = 0; x < curDate.length; x++) {
- if (selected.year === curDate[x].year && selected.month === curDate[x].month && curDate[x].date === day) {
- return 'cur'
- }
- }
- return ''
- }
- //上一月
- const prevMonthClick = () => {
- let {year,month} = selectedDate.value
- let years = year, months;
- if (month === 1) {
- years = year - 1;
- months = 12;
- } else {
- months = month - 1;
- }
- selectedDate.value = {
- year: years,
- month: months
- }
- getDatesDay(years,months)
- }
- //下一月
- const nextMonthClick = () => {
- let {year,month} = selectedDate.value
- let years, months;
- if (month === 12) {
- years = year + 1;
- months = 1;
- } else {
- years = year;
- months = month + 1;
- }
- selectedDate.value = {
- year: years,
- month: months
- }
- getDatesDay(years,months)
- }
- //天被点击
- const datesDayClick = (item) => {
- if (item.type !== 'excluded') {
- let {year,month} = selectedDate.value
- choiceDate.value = {year: year, month: month, date: item.key}
- getDatesDay(year, month)
- backChoiceDate()
- }
- }
- //下拉日期选择
- const datePickerChange = (val) => {
- const toDayJs = dayjs(val);
- toPicker.value = toDayJs.format('YYYY-MM')
- getDatesDay(toDayJs.year(), toDayJs.month() + 1)
- }
- //返回选择的日期
- const backChoiceDate = () => {
- //选择的日期处理
- const choiceVal = isDayDateFormat(choiceDate.value)
- //今天的日期处理
- const today = isDayDateFormat(toDays.value)
- //判断处理
- if (choiceVal.choice > today.choice) {
- backToDay()
- } else {
- emit('choice-date', choiceVal)
- }
- }
- //回到今天
- const backToDay = () => {
- const {year, month ,date} = toDays.value ?? {};
- selectedDate.value = {year: year, month: month}
- choiceDate.value = {year: year, month: month, date: date}
- getDatesDay(year,month)
- emit('choice-date', isDayDateFormat(toDays.value))
- }
- //格式转换
- const isDayDateFormat = ({year, month, date}) => {
- const today = {
- year: year,
- month: zpadStart(month, 2, '0'),
- date: zpadStart(date, 2, '0')
- }
- const choice = today.year + today.month + today.date
- const choices = `${today.year}-${today.month}-${today.date}`
- return {date: today, choice, choices, dates: {year, month, date}}
- }
- const zpadStart = (val, leng, pad) => {
- val += ''
- while (val.length < leng) {
- val = pad + val
- }
- return val
- }
- </script>
- <style lang="scss" scoped>
- @import './style.scss';
- </style>
|