一、页面样式
二、代码实现
<!--
* @Author: Varian LIn
* @Date: 2022-04-01 15:04:15
* @LastEditors: coco
* @LastEditTime: 2022-04-06 17:33:28
* @Description:
-->
<template>
<div class="date-pick">
<div class="header">
<p>时间跳转</p>
<el-icon class="icon cp"><d-arrow-left /></el-icon>
</div>
<!-- 日历内容 -->
<div class="content">
<div class="content-top">
<div class="content-top-arrows">
<a href="javascript:;" id="option" @click="selectMonth"
>{{ state.chinese[state.comp_time.split("/")[1] - 1] }}月</a
>
<div id="arrows" class="arrows-month">
<a href="javscript:;" id="prev" @click="prevMonth"
><el-icon><caret-top /></el-icon
></a>
<a href="javascript:;" id="next" @click="nextMonth"
><el-icon><caret-bottom /></el-icon
></a>
</div>
</div>
<div class="content-top-arrows">
<a href="javascript:;" id="option" @click="selectYear"
>{{ state.comp_time.split("/")[0] }}年</a
>
<div id="arrows" class="arrows-year">
<a href="javscript:;" id="prev" @click="prevYear"
><el-icon><caret-top /></el-icon
></a>
<a href="javascript:;" id="next" @click="nextYear"
><el-icon><caret-bottom /></el-icon
></a>
</div>
</div>
</div>
<div class="caculater" v-show="state.showMonth && state.showYear">
<div class="content-center">
<ul class="content-center-weekday">
<li v-for="(item, index) in state.weekday" :key="index">{{ item }}</li>
</ul>
</div>
<div class="content-bottom">
<ul
class="content-bottom-row"
v-for="(item, index) in state.dayAry"
:key="index"
>
<li
class="content-bottom-day"
:class="{ gray: !el.cur, dayBorder: el.isSelect }"
@click="getToday(el)"
v-for="(el, index) in item"
:key="index"
>
<span class="day-border"> {{ el.text }}</span>
</li>
</ul>
</div>
</div>
<!-- 月份或年份选择 -->
<YearMonthPick v-show="!state.showMonth ||!state.showYear" :txt="123"/>
</div>
<!-- 日历内容 -->
<div class="hour-pick">
<div class="hour-pick-time">
<a href="javascript:;" id="option">17时</a>
<div id="arrows" class="arrows-hour">
<a href="javscript:;" id="prev"
><el-icon><caret-top /></el-icon
></a>
<a href="javascript:;" id="next"
><el-icon><caret-bottom /></el-icon
></a>
</div>
</div>
<div class="hour-pick-icon">:</div>
<div class="hour-pick-time">
<a href="javascript:;" id="option">54分</a>
<div id="arrows" class="arrows-minute">
<a href="javscript:;" id="prev"
><el-icon><caret-top /></el-icon
></a>
<a href="javascript:;" id="next"
><el-icon><caret-bottom /></el-icon
></a>
</div>
</div>
</div>
<div class="confirm">
<el-button class="confirm-btn" type="primary" round>确定</el-button>
<el-button class="confirm-btn" type="primary" round>取消</el-button>
</div>
</div>
</template>
<script setup>
import { reactive } from "@vue/reactivity";
import YearMonthPick from './YearMonthPick.vue';
//import { renderList, watch } from "@vue/runtime-core";
// let props =defineProps({valuemodel:String, });
const myDate = new Date();
const state = reactive({
//六行
dayAry: [],
timeStr: "",
weekday :["日", "一", "二", "三", "四", "五", "六"],
chinese :[
"一",
"二",
"三",
"四",
"五",
"六",
"七",
"八",
"九",
"十",
"十一",
"十二",
],
comp_time:
myDate.getFullYear() +
"/" +
(myDate.getMonth() + 1) +
"/" +
myDate.getDate(), //props.valuemodel"2022/4/8"
todayDate: myDate.getFullYear() +
"/" +
(myDate.getMonth() + 1) +
"/" +
myDate.getDate(),
todayMonth:(myDate.getMonth() + 1) ,
todayYear: myDate.getFullYear(),
showMonth:true,
showYear:true,
});
state.dayAry = getRenderData(state.comp_time);
console.log("2222", myDate.getFullYear());
//value '年月日'
//获取当前的月份对应的天数和1号对应的日期"2022/4/8"
function getRenderData(value) {
// debugger
let dayAry = [];
function getDayNum(str) {
console.log(str, "str");
let arr = str.split("/");
let y = arr[0],
m = arr[1];
//返回每月的1号的日期
return [new Date(y, m, 0).getDate(), new Date(y, m-1 , 1).getDay()];//
}
let [nums, first] = getDayNum(value);
let n = 1;
let nextMonthDay = 1;
console.log(new Date('2022-4-1').getDay(),nums, first,dayAry );//30 5
function getLastMonthDays(str) {
let arr = str.split("/");
let y = arr[0],
m = arr[1];
//获取上个月的1号的日期
let data = new Date(y, m - 1, 1);
return new Date(data.getFullYear(), data.getMonth(), 0).getDate();
}
let preMonthDay = getLastMonthDays(value); //上一个月的最后一天
console.log(preMonthDay);//31
for (let i = 0; i < 6; i++) {
let temp = [];
for (var j = 0; j < 7; j++) {
if (i == 0) {
if (j < first) {
temp.unshift({
isSelect: false,
cur: false,
text: preMonthDay--,
yearTime:state.comp_time,
});
} else {
let obj = {
isSelect: false,
cur: true,
text: n++,
yearTime:state.comp_time,
};
if (obj.text == value.split("/")[2] && obj.yearTime == state.todayDate) {
obj.isSelect = true;
}
temp.push(obj);
}
} else {
let t = n++;
if (t > nums) {
temp.push({
isSelect: false,
cur: false,
text: nextMonthDay++,
yearTime:state.comp_time,
});
} else {
let obj = {
isSelect: false,
cur: true,
text: t,
yearTime:state.comp_time,
};
if (obj.text == value.split("/")[2] && obj.yearTime == state.todayDate) {
obj.isSelect = true;
}
temp.push(obj);
}
}
}
dayAry.push(temp);
}
return dayAry;
}
const prevYear = () => {
let arr = state.comp_time.split("/");
arr[0]--;
state.comp_time = arr.join("/");
state.dayAry = getRenderData(state.comp_time);
};
const nextYear = () => {
let arr = state.comp_time.split("/");
arr[0]++;
state.comp_time = arr.join("/");
state.dayAry = getRenderData(state.comp_time);
};
const prevMonth = () => {
let arr = state.comp_time.split("/");
let m = arr[1] / 1;
if (m - 1 <= 0) {
arr[1] = 12;
arr[0]--;
} else {
arr[1]--;
}
state.comp_time = arr.join("/");
state.dayAry = getRenderData(state.comp_time);
};
const nextMonth = () => {
let arr = state.comp_time.split("/");
let m = arr[1] / 1;
if (m + 1 > 12) {
arr[1] = 1;
arr[0]++;
} else {
arr[1]++;
}
state.comp_time = arr.join("/");
state.dayAry = getRenderData(state.comp_time);
};
const getToday = (el) => {
if (el.cur) {
let ary = state.comp_time.split("/");
ary[2] = el.text;
}
};
const selectMonth =()=>{
state.showMonth=!state.showMonth
}
const selectYear =()=>{
state.showYear=!state.showYear
}
/*watch(
()=>state.comp_time,
(str)=>{
renderTitle(str);
}
);
function renderTitle(str){
let ary=str.split('/');
state.timeStr=ary[0]+"年"+ary[1]+"月"+ary[2]+"日";
state.dayAry=getRenderData(str);
}
renderTitle('2022/4/8'); */
// state.dayAry=getRenderData(props.valuemodel);
/* export default {
name: "",
}; */
/*
const emit =defineEmit([ "update:valuemodel","change"]);
const fn=()=>{
emit("change",1,2)
} */
</script>
<style lang="scss" scoped>
.date-pick {
width: 520px;
max-height: 550px;
min-height: 450px;
border-radius: 10px 10px 2px 2px;
background: rgba(11, 33, 66, 0.8);
margin-bottom: 2px;
position: absolute;
left: 0;
bottom: 140px;
}
.header {
margin: 0 10px;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
p {
margin: 12px 10px;
color: rgba(201, 213, 226, 1);
}
.icon {
transform: rotate(-90deg);
margin-right: 10px;
}
&::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background: rgba(11, 63, 116, 1);
// background: #fff;
}
}
///添加代码
.content {
margin: 20px 45px;
//display: flex;
position: relative;
&::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 426px;
height: 1px;
background: #546680;
}
.content-top {
//position: absolute;
top: 0;
margin-bottom: 10px;
width: 426px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 18px;
font-family: Microsoft YaHei;
font-weight: bold;
color: #c9d5e2;
}
.content-center{
margin: 20px 0px;
.content-center-weekday {
//position: absolute;
display: flex;
width: 426px;
justify-content: space-between;
align-items: center;
font-size: 16px;
font-family: Microsoft YaHei;
font-weight: bold;
color: #556c84;
cursor: default;
}
}
.content-bottom {
// margin: 80px 0px 0px 0px;
font-size: 18px;
font-family: Microsoft YaHei;
font-weight: 400;
.content-bottom-row {
display: flex;
width: 426px;
justify-content: space-between;
align-items: center;
.content-bottom-day {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
margin: 3px 0 10px 0;
color: #a6b7c9;
border-radius: 50%;
border: solid 1px transparent;
width: 28px;
height: 28px;
}
.content-bottom-day:hover {
border: 1px solid #3193ff;
}
.gray {
color: #a6b7c970;
}
.dayBorder {
background: #3193ff;
}
}
}
}
//时分
.hour-pick {
margin: 0 75px;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
font-size: 24px;
font-family: Microsoft YaHei;
font-weight: bold;
color: #c9d5e2;
cursor: default;
.hour-pick-time {
width: 146px;
height: 55px;
background: #021c35;
box-shadow: 0px 4px 6px 0px rgba(11, 33, 66, 0.14);
border-radius: 10px;
justify-content: center;
align-items: center;
}
}
//确认按钮
.confirm {
margin: 15px 45px;
display: flex;
position: relative;
justify-content: end;
align-items: center;
.confirm-btn {
width: 100px;
height: 36px;
}
}
// 时间按键位置颜色变化
.content-top-arrows,
.hour-pick-time {
display: flex;
#arrows {
margin-left: 10px;
#next {
margin-top: -15px;
display: flex;
}
}
}
a:hover {
color: #3193ff !important;
}
</style>