vue3日歷控件的具體實現(xiàn)
更新時間:2023年02月01日 15:23:37 作者:強(qiáng)風(fēng)吹拂str
日歷在很多地方都可以使用的到,本文主要介紹了vue3日歷控件的具體實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
很多地方都要用到日歷控件,比如生日、出發(fā)到達(dá)日期等等,本文就來介紹一下vue3日歷控件的具體實現(xiàn),具體如下
效果如下:
<template> <div class="cal_con" style="margin-left:200px"> <div class="cal_header"> <!-- 頂部左側(cè) --> <div class="cal_header_left"> <div class="cal_header_left_top"> <span class="cal_h_time">{{ year }}</span> </div> <div class="cal_header_left_bottom"> <div class="cal_h_left"> <div class="cal_h_btn" @click="preYear"> <svg class="cal_h_l_icon"> <!-- 畫線條 --> <polyline points="6,0 2,4 6,8" style="fill: none; stroke: #ffffff; stroke-width: 2" /> <!-- 畫線條 --> <polyline points="10,0 6,4 10,8" style="fill: none; stroke: #ffffff; stroke-width: 2" /> </svg> </div> <div class="cal_h_btn" @click="preMonth"> <svg class="cal_h_l_icon"> <polyline points="6,0 2,4 6,8" style="fill: none; stroke: #ffffff; stroke-width: 2" /> </svg> </div> </div> <div class="cal_h_center"> <span class="cal_h_time">{{ month }}</span> </div> <div class="cal_h_right"> <div class="cal_h_btn" @click="nextMonth"> <svg class="cal_h_l_icon"> <polyline points="2,0 8,4 2,8" style="fill: none; stroke: #ffffff; stroke-width: 2" /> </svg> </div> <div class="cal_h_btn" @click="nextYear"> <svg class="cal_h_l_icon"> <polyline points="2,0 8,4 2,8" style="fill: none; stroke: #ffffff; stroke-width: 2" /> <polyline points="6,0 12,4 6,8" style="fill: none; stroke: #ffffff; stroke-width: 2" /> </svg> </div> </div> </div> </div> <!-- 頂部右側(cè) --> <div class="cal_header_right"> <div class="nameText">姓名:張三</div> <div class="QingjiaText">請假:{{jobTime["請假"]}}h</div> <div class="JiaBanText">加班:{{jobTime["加班"]}}h</div> <div class="ChuCaiText">出差:{{jobTime["出差"]}}h</div> <div class="YiChangText">異??记?{{jobTime["異常卡"]}}次</div> </div> </div> <div class="cal_month"> <!--日歷表頭 周一 周二 周三 周四 周五 周六 周日--> <div class="cal_m_weeks"> <div v-for="w in weeks" :key="w" class="cal_m_weeks_cell"> {{ w }} </div> </div> <!--日歷表內(nèi)容 --> <div class="cal_m_days"> <!-- 第幾行 --> <div v-for="(ds, index) in monthData" :key="index" class="cal_m_day_line" > <!-- 每行內(nèi)容 --> <div v-for="d in ds" :key="d.day" class="cal_m_day_cell" :style="{ color: getCellColor(d) }" @mouseenter="mouseenter(d, $event)" @mouseleave="mouseleave(d, $event)" > <div class="itemDay">{{ d.day }}</div> <!-- {{ ds[index].date.Format("yyyy-MM-dd") }} --> <!-- {{ d.date.Format("yyyy-MM-dd") }} --> <slot :name="d.fullYear + '-' + d.month + '-' + d.day"></slot> <!-- 正???--> <div v-if=" d.type == 0 && setDataList(d.date).typeName == '正??? " class="ZhengChang" > <div class="ZhengChangTitle">正常卡:{{setDataList(d.date).jobTime}}次</div> <div class="ZhengChangDian"> <div></div> <div></div> <div></div> </div> </div> <!-- 請假 --> <div v-if=" d.type == 0 && setDataList(d.date).typeName == '請假' " class="Qingjia" > <div class="QingjiaTitle">請假:事假{{setDataList(d.date).jobTime}}</div> <div class="QingjiaDian"> <div></div> <div></div> <div></div> </div> </div> <!-- 加班 --> <div v-if=" d.type == 0 && setDataList(d.date).typeName == '加班' " class="JiaBan" > <div class="JiaBanTitle">加班:{{setDataList(d.date).jobTime}}h</div> <div class="JiaBanDian"> <div></div> <div></div> <div></div> </div> </div> <!-- 出差 --> <div v-if=" d.type == 0 && setDataList(d.date).typeName == '出差' " class="ChuChai" @click="ss(index)" > <div class="ChuChaiTitle">出差{{setDataList(d.date).jobTime}}</div> <div class="ChuChaiDian"> <div></div> <div></div> <div></div> </div> </div> <!-- 異???--> <div v-if=" d.type == 0 && setDataList(d.date).typeName == '異??? " class="YiChang" @click="ss(index)" > <div class="YiChangTitle">異常卡{{setDataList(d.date).jobTime}}</div> <div class="YiChangDian"> <div></div> <div></div> <div></div> </div> </div> <!-- 假期 --> <div v-if=" d.type == 0 && setDataList(d.date).typeName == '假期' " class="JiaQi" > <div class="JiaQiTitle">假期{{setDataList(d.date).jobTime}}</div> <div class="JiaQiDian"> <div></div> <div></div> <div></div> </div> </div> </div> </div> </div> </div> </div> </template> <script setup> import {ref, reactive, toRefs, onMounted, defineEmits} from "vue"; import {ElMessage, ElMessageBox} from "element-plus"; import {Solar, Lunar} from "lunar-javascript"; const $emit = defineEmits(["enter", "leave", "changeMonth"]) const dataList = reactive({ datas: [ { time: "2023-01-29", typeName: "正???, jobTime: 8 }, { time: "2023-01-10", typeName: "請假", jobTime: 8 }, { time: "2023-01-10", typeName: "請假", jobTime: 8 }, { time: "2023-01-22", typeName: "加班", jobTime: 4 }, { time: "2023-01-11", typeName: "出差", jobTime: 14 }, { time: "2023-01-14", typeName: "異常卡", jobTime: 8 }, { time: "2023-01-02", typeName: "假期", jobTime: 11 }, ], }) let now = ref(new Date()) //當(dāng)前時間:Fri Jul 29 2022 09:57:33 GMT+0800 (中國標(biāo)準(zhǔn)時間) let year = ref(0) let month = ref(0) let jobTime = ref([]) const weeks = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"] let monthData = ref([]) //月數(shù)據(jù)容器 let currentYear = ref(new Date().getFullYear()) //當(dāng)前年:2022 let currentMonth = ref(new Date().getMonth() + 1) //當(dāng)前月:7 let currentDay = ref(new Date().getDate()) //當(dāng)前天:29 onMounted(() => { setYearMonth(now.value); generateMonth(now.value); getJobTime() }) function getJobTime(){ dataList.datas.forEach((item) => { console.log("223",jobTime) // check if animal type has already been added to newObj if(!jobTime.value[item.typeName]){ // If it is the first time seeing this animal type // we need to add title and points to prevent errors jobTime.value[item.typeName] = {}; jobTime.value[item.typeName] = 0; } // add animal points to newObj for that animal type. jobTime.value[item.typeName] += item.jobTime }) console.log("22",JSON.stringify(jobTime.value["請假"])) } // 通過輸入日期,匹配當(dāng)天的所有數(shù)據(jù) // 入?yún)⒏袷?value:'2022-07-09' function setDataList(value) { let object = {}; const date = dateFormat("YYYY-mm-dd", value) dataList.datas.forEach((element) => { if (element.time == date) { object = element; } }); return object; } function setYearMonth(now) { year.value = now.getFullYear(); month.value = now.getMonth() + 1; } function preYear() { let n = now.value; let date = new Date( n.getFullYear() - 1, n.getMonth(), n.getDate(), n.getHours(), n.getMinutes(), n.getSeconds(), n.getMilliseconds() ); setYearMonthInfos(date); } function preMonth() { let n = now.value; let date = new Date( n.getFullYear(), n.getMonth() - 1, n.getDate(), n.getHours(), n.getMinutes(), n.getSeconds(), n.getMilliseconds() ); setYearMonthInfos(date); } function nextYear() { let n = now.value; let date = new Date( n.getFullYear() + 1, n.getMonth(), n.getDate(), n.getHours(), n.getMinutes(), n.getSeconds(), n.getMilliseconds() ); setYearMonthInfos(date); } function nextMonth() { let n = now.value; let date = new Date( n.getFullYear(), n.getMonth() + 1, n.getDate(), n.getHours(), n.getMinutes(), n.getSeconds(), n.getMilliseconds() ); setYearMonthInfos(date); } function setYearMonthInfos(date) { setYearMonth(date); generateMonth(date); now.value = date; dateChange(); } function generateMonth(date) { date.setDate(1); // 星期 0 - 6, 星期天 - 星期6 let weekStart = date.getDay(); let endDate = new Date(date.getFullYear(), date.getMonth() + 1, 0); let dayEnd = endDate.getDate(); // 星期 0 - 6, 星期天 - 星期6 let weeEnd = endDate.getDay(); let milsStart = date.getTime(); let dayMils = 24 * 60 * 60 * 1000; let milsEnd = endDate.getTime() + dayMils; let monthDatas = []; let current; // 上個月的幾天 for (let i = 1; i < weekStart; i++) { current = new Date(milsStart - (weekStart - i) * dayMils); monthDatas.push({ type: -1, date: current, fullYear: current.getFullYear(), month: current.getMonth() + 1, day: current.getDate(), }); } // 當(dāng)前月 for (let i = 0; i < dayEnd; i++) { current = new Date(milsStart + i * dayMils); monthDatas.push({ type: 0, date: current, fullYear: current.getFullYear(), month: current.getMonth() + 1, day: current.getDate(), }); } // 下個月的幾天 for (let i = 0; i < 6 - weeEnd + 1; i++) { current = new Date(milsEnd + i * dayMils); monthDatas.push({ type: 1, date: current, fullYear: current.getFullYear(), month: current.getMonth() + 1, day: current.getDate(), }); } monthData.value = []; for (let i = 0; i < monthDatas.length; i++) { let mi = i % 7; if (mi == 0) { monthData.value.push([]); } monthData.value[Math.floor(i / 7)].push(monthDatas[i]); } // 少于6行,補(bǔ)足6行 if (monthData.value.length <= 5) { milsStart = current.getTime(); let lastLine = []; for (let i = 1; i <= 7; i++) { current = new Date(milsStart + i * dayMils); lastLine.push({ type: 1, date: current, fullYear: current.getFullYear(), month: current.getMonth() + 1, day: current.getDate(), }); } monthData.value.push(lastLine); } console.log("http://", JSON.parse(JSON.stringify(monthData.value))) } function getCellColor(d) { if ( d.fullYear == currentYear.value && d.month == currentMonth.value && d.day == currentDay.value ) { return "#409eff"; } let color = d.type == -1 ? "#c0c4cc" : d.type == 1 ? "#c0c4cc " : ""; return color; } function mouseenter(d, event) { $emit("enter", event, d); // document.getElementsByClassName('cal_m_day_cell').style('background-color','#000000') } function mouseleave(d, event) { $emit("leave", event, d); } function dateChange() { let fullYear = now.value.getFullYear(); let month = now.value.getMonth(); let startDay = new Date(fullYear, month, 1); let endDay = new Date(fullYear, month + 1, 0, 23, 59, 59); $emit("changeMonth", startDay, endDay); } function dateFormat(fmt, date) { let ret; const opt = { "Y+": date.getFullYear().toString(), // 年 "m+": (date.getMonth() + 1).toString(), // 月 "d+": date.getDate().toString(), // 日 "H+": date.getHours().toString(), // 時 "M+": date.getMinutes().toString(), // 分 "S+": date.getSeconds().toString() // 秒 // 有其他格式化字符需求可以繼續(xù)添加,必須轉(zhuǎn)化成字符串 }; for (let k in opt) { ret = new RegExp("(" + k + ")").exec(fmt); if (ret) { fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))) } ; } ; return fmt; } </script> <style scoped lang="scss"> .cal_con { box-sizing: border-box; width: 1020px; //下方單元格*7+左右內(nèi)邊距 140*7+20+20 padding: 10px 20px 20px 20px; -webkit-user-select: none; //取消鼠標(biāo)點(diǎn)快了文字會被選中。 -moz-user-select: none; //取消鼠標(biāo)點(diǎn)快了文字會被選中。 -ms-user-select: none; //取消鼠標(biāo)點(diǎn)快了文字會被選中。 user-select: none; //取消鼠標(biāo)點(diǎn)快了文字會被選中。 color: #000000; box-shadow: 0 2px 12px 0 #0000006e; background: #ffffff; border-radius: 20px; .cal_header { width: 980px; //下方單元格*7 140*7 height: 80px; display: flex; align-items: center; justify-content: space-between; .cal_header_left { display: flex; flex-direction: column; align-items: center; .cal_header_left_top { width: 122px; height: 30px; background: #109af9; display: flex; align-items: center; justify-content: center; .cal_h_time { font-family: "Microsoft YaHei"; font-style: normal; font-weight: 400; font-size: 20px; color: #ffffff; } } .cal_header_left_bottom { width: 122px; height: 30px; background: rgba(16, 154, 249, 0.6); display: flex; align-items: center; justify-content: space-between; .cal_h_left { height: 100%; display: flex; .cal_h_btn { height: 100%; width: 24px; cursor: pointer; display: flex; align-items: center; justify-content: center; } .cal_h_btn:hover { background-color: #109af9; } .cal_h_l_icon { height: 8px; width: 12px; margin: auto; } } .cal_h_center { .cal_h_time { font-family: "Microsoft YaHei"; font-style: normal; font-weight: 400; font-size: 20px; color: #ffffff; } } .cal_h_right { height: 100%; display: flex; .cal_h_btn { height: 100%; width: 24px; cursor: pointer; display: flex; align-items: center; justify-content: center; } .cal_h_btn:hover { background-color: #109af9; } .cal_h_l_icon { height: 8px; width: 12px; margin: auto; } } } } .cal_header_right { // width: 1125px; height: 43px; font-family: "Microsoft YaHei"; font-style: normal; font-weight: 400; font-size: 20px; line-height: 26px; display: flex; align-items: center; justify-content: center; .QingjiaText { color: rgba(255, 199, 0, 1); margin-left: 80px; } .JiaBanText { color: rgba(36, 0, 255, 1); margin-left: 80px; } .ChuCaiText { color: rgba(255, 167, 40, 1); margin-left: 80px; } .YiChangText { color: rgba(240, 92, 39, 1); margin-left: 80px; } } } .cal_month { // 日歷表頭 周日 周一 周二 周三 周四 周五 周六 .cal_m_weeks { display: flex; .cal_m_weeks_cell { box-sizing: border-box; width: 140px; height: 30px; font-weight: 400; font-size: 16px; border: 1px solid #e4e7ed; display: flex; align-items: center; justify-content: center; color: rgba(0, 0, 0, 0.45); } } // 日歷表內(nèi)容 .cal_m_days { // 第幾行 .cal_m_day_line { display: flex; // 每行內(nèi)容 .cal_m_day_cell { box-sizing: border-box; width: 140px; height: 120px; border: 1px solid #e4e7ed; .itemDay { width: 100%; height: 30px; font-style: normal; font-weight: 400; font-size: 24px; text-align: right; box-sizing: border-box; padding-right: 10px; } } // 每行內(nèi)容-浮動效果 .cal_m_day_cell:hover { color: #409eff; } } } } } // 正??? .ZhengChang { margin: 0px 0px 0px 8px; width: 120px; height: 35px; border-radius: 10px; display: flex; justify-content: space-between; align-items: center; padding: 0px 10px; background: rgba(16, 154, 249, 0.2); color: rgba(16, 154, 249, 1); .ZhengChangTitle { } .ZhengChangDian { div { width: 4px; height: 4px; margin-bottom: 2px; border-radius: 4px; background: rgba(16, 154, 249, 1); } } } .ZhengChang:hover { transform: scale(1.1); } // 請假 .Qingjia { margin: 0px 0px 0px 8px; width: 120px; height: 35px; border-radius: 10px; display: flex; justify-content: space-between; align-items: center; padding: 0px 10px; background: rgba(255, 199, 0, 0.2); color: rgba(255, 199, 0, 1); .QingjiaTitle { } .QingjiaDian { div { width: 4px; height: 4px; margin-bottom: 2px; border-radius: 4px; background: rgba(255, 199, 0, 1); } } } .Qingjia:hover { transform: scale(1.1); } // 加班 .JiaBan { margin: 0px 0px 0px 8px; width: 120px; height: 35px; border-radius: 10px; display: flex; justify-content: space-between; align-items: center; padding: 0px 10px; background: rgba(36, 0, 255, 0.2); color: rgba(36, 0, 255, 1); .JiaBanTitle { } .JiaBanDian { div { width: 4px; height: 4px; margin-bottom: 2px; border-radius: 4px; background: rgba(36, 0, 255, 1); } } } .JiaBan:hover { transform: scale(1.1); } // 出差 .ChuChai { margin: 0px 0px 0px 8px; width: 120px; height: 35px; border-radius: 10px; display: flex; justify-content: space-between; align-items: center; padding: 0px 10px; background: rgba(255, 167, 40, 0.2); color: #ffa728; .ChuChaiTitle { } .ChuChaiDian { div { width: 4px; height: 4px; margin-bottom: 2px; border-radius: 4px; background: #ffa728; } } } .ChuChai:hover { transform: scale(1.1); } // 異常卡 .YiChang { margin: 0px 0px 0px 8px; width: 120px; height: 35px; border-radius: 10px; display: flex; justify-content: space-between; align-items: center; padding: 0px 10px; background: rgba(240, 92, 39, 0.2); color: rgba(240, 92, 39, 1); .YiChangTitle { } .YiChangDian { div { width: 4px; height: 4px; margin-bottom: 2px; border-radius: 4px; background: rgba(240, 92, 39, 1); } } } .YiChang:hover { transform: scale(1.1); } // 假期 .JiaQi { margin: 0px 0px 0px 8px; width: 120px; height: 35px; border-radius: 10px; display: flex; justify-content: space-between; align-items: center; padding: 0px 10px; background: rgba(29, 209, 155, 0.2); color: rgba(29, 209, 155, 1); .JiaQiTitle { } .JiaQiDian { div { width: 4px; height: 4px; margin-bottom: 2px; border-radius: 4px; background: rgba(29, 209, 155, 1); } } } .JiaQi:hover { transform: scale(1.1); } </style>
到此這篇關(guān)于vue3日歷控件的具體實現(xiàn)的文章就介紹到這了,更多相關(guān)vue3日歷控件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:
相關(guān)文章
vue video和vue-video-player實現(xiàn)視頻鋪滿教程
這篇文章主要介紹了vue video和vue-video-player實現(xiàn)視頻鋪滿教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10vuejs+element-ui+laravel5.4上傳文件的示例代碼
本篇文章主要介紹了vuejs+element-ui+laravel5.4上傳文件的示例代碼,具有一定的參考價值,有興趣的可以了解一下2017-08-08elementui使用el-upload組件實現(xiàn)自定義上傳的詳細(xì)步驟
upload上傳是前端開發(fā)很常用的一個功能,在Vue開發(fā)中常用的Element組件庫也提供了非常好用的upload組件,這篇文章主要給大家介紹了關(guān)于elementui使用el-upload組件實現(xiàn)自定義上傳的詳細(xì)步驟,需要的朋友可以參考下2023-12-12