本文实例为大家分享了vue实现钉钉的考勤日历的具体代码,供大家参考,具体内容如下
直接上效果图,需要再往下看
GitHub地址:vue-calendar-component
由于需要对此组件的样式及功能的扩展,直接复制代码过来修改,开始贴代码,很长很长 慢慢看
checkCalendar.vue(子组件)
<style lang=\"scss\" rel=\"stylesheet/scss\"> @media screen and (min-width: 460px) { .wh_item_date:hover { background: #71c7a5; cursor: pointer; } } * { margin: 0; padding: 0; } .wh_container { max-width: 410px; margin: auto; } li { list-style-type: none; } .wh_top_title { display: flex; } .wh_top_title li { cursor: pointer; display: flex; color: #fff; font-size: 18px; flex: 1; justify-content: center; align-items: center; height: 47px; } .wh_top_title .wh_content_li { cursor: auto; flex: 2.5; color: black; } .wh_content_all { font-family: -apple-system, BlinkMacSystemFont, \"PingFang SC\", \"Helvetica Neue\", STHeiti, \"Microsoft Yahei\", Tahoma, Simsun, sans-serif; background-color: white; width: 100%; overflow: hidden; padding-bottom: 8px; } .wh_content { display: flex; flex-wrap: wrap; padding: 0 3% 0 3%; width: 100%; } .wh_content:first-child .wh_content_item_tag, .wh_content:first-child .wh_content_item { color: #ddd; font-size: 16px; } .wh_content_item, wh_content_item_tag { font-size: 15px; width: 13.4%; text-align: center; color: #fff; position: relative; } .wh_content_item { height: 40px; } .wh_top_tag { width: 40px; height: 40px; line-height: 40px; margin: auto; display: flex; justify-content: center; align-items: center; color: black; } .wh_item_date { width: 30px; height: 30px; line-height: 30px; margin: auto; display: flex; justify-content: center; align-items: center; color: black; .smallDot { background-color: #f99341; width: 5px; height: 5px; border-radius: 50%; text-align: center; margin-left: 13px; } .smallDot1 { background-color: #1989fa; width: 5px; height: 5px; border-radius: 50%; text-align: center; margin-left: 13px; } } .wh_left { width: 12px; height: 12px; border-top: 2px solid #ffffff; border-left: 2px solid #ffffff; transform: rotate(-45deg); border-color: black; } .wh_left:active, .wh_right:active { border-color: #ddd; } .wh_right { width: 12px; height: 12px; border-top: 2px solid #ffffff; border-right: 2px solid #ffffff; transform: rotate(45deg); border-color: black; } .wh_content_item > .wh_isMark { margin: auto; border-radius: 50%; background: blue; z-index: 2; } .wh_content_item .wh_other_dayHide { color: #bfbfbf; } .wh_content_item .wh_want_dayHide { color: #bfbfbf; } .wh_content_item .wh_isToday { background: #77adfa; border-radius: 50%; } .wh_content_item .wh_chose_day { background: #1989fa; border-radius: 50%; } </style> <template> <section class=\"wh_container\"> <div class=\"wh_content_all\"> <div class=\"wh_top_title\"> <li @click=\"PreMonth(myDate,false)\"> <div class=\"wh_left\"></div> </li> <li class=\"wh_content_li\">{{dateTop}}</li> <li @click=\"NextMonth(myDate,false)\"> <div class=\"wh_right\"></div> </li> </div> <div class=\"wh_content\"> <div class=\"wh_content_item\" v-for=\"tag in textTop\"> <div class=\"wh_top_tag\">{{tag}}</div> </div> </div> <div class=\"wh_content\"> <div class=\"wh_content_item\" v-for=\"(item,index) in list\" @click=\"clickDay(item,index)\"> <div class=\"wh_item_date\" style=\"display: block\" v-bind:class=\"[{ wh_isMark: item.isMark},{wh_other_dayHide:item.otherMonth!==\'nowMonth\'},{wh_want_dayHide:item.dayHide},{wh_isToday:item.isToday},{wh_chose_day:item.chooseDay},setClass(item)]\"> {{item.id}} <!--这里是控制异常、正常的那个小圆点--> <span v-for=\"(date,index) in dateList\" :key=\"index\"> <span v-if=\"date.offDutyTime&&date.onDutyTime&&formatDate(date.recordDate)==item.date&&(isLate(date.serverEndTime,date.offDutyTime)||isLate(date.onDutyTime,date.serverStartTime))\"> <div class=\"smallDot\"></div> </span> <span v-if=\"date.offDutyTime&&date.onDutyTime&&formatDate(date.recordDate)==item.date&&!isLate(date.serverEndTime,date.offDutyTime)&&!isLate(date.onDutyTime,date.serverStartTime)\"> <div class=\"smallDot1\"></div> </span> </span> </div> </div> </div> </div> </section> </template> <script> import timeUtil from \"./calendar\"; export default { data() { return { myDate: [], list: [], historyChose: [], dateTop: \"\", loginNannyUser: {}, loginGzhUser: {}, dateList: [] }; }, props: { markDate: { type: Array, default: () => [] }, markDateMore: { type: Array, default: () => [] }, textTop: { type: Array, default: () => [\"一\", \"二\", \"三\", \"四\", \"五\", \"六\", \"日\"] }, sundayStart: { type: Boolean, default: () => false }, agoDayHide: { type: String, default: `0` }, futureDayHide: { type: String, default: `2554387200` }, joinWishId: { default: null } }, created() { let $this = this; this.getLoginAllUser(\"nanny\", {}, function () {//这里只是我这边的业务,删除就行 }); this.intStart();//初始化数据 this.myDate = new Date(); }, methods: { isLate(str, str1) {//判断两个时分秒大小 return new Date((this.formatDates(new Date()) + \" \" + str).replace(/-/g, \'/\')) > new Date((this.formatDates(new Date()) + \" \" + str1).replace(/-/g, \'/\')); }, formatDate(date) { date = typeof date === \'string\' ? new Date(date.replace(/\\-/g, \'/\')) : date; return date.getFullYear() + \'/\' + (date.getMonth() + 1) + \'/\' + date.getDate(); }, intStart() { timeUtil.sundayStart = this.sundayStart; }, setClass(data) { let obj = {}; obj[data.markClassName] = data.markClassName; return obj; }, clickDay(item, index) { if (item.otherMonth === \"nowMonth\" && !item.dayHide) { this.getList(this.myDate, item.date); } if (item.otherMonth !== \"nowMonth\") { item.otherMonth === \"preMonth\" ? this.PreMonth(item.date) : this.NextMonth(item.date); } }, ChoseMonth(date, isSelectedDay = true) { date = timeUtil.dateFormat(date); this.myDate = new Date(date); this.$emit(\"changeMonth\", timeUtil.dateFormat(this.myDate)); if (isSelectedDay) { this.getList(this.myDate, date, isSelectedDay); } else { this.getList(this.myDate); } }, PreMonth(date, isSelectedDay = true) { date = timeUtil.dateFormat(date); this.myDate = timeUtil.getOtherMonth(this.myDate, \"preMonth\"); this.$emit(\"changeMonth\", timeUtil.dateFormat(this.myDate)); this.axiosPost(\"/nannyCheckIn/findMonthList.n\", {date: this.myDate,joinWishListId: this.joinWishId,}, function (resData) { this.dateList = resData.list; }); if (isSelectedDay) { this.getList(this.myDate, date, isSelectedDay); } else { this.getList(this.myDate); } }, NextMonth(date, isSelectedDay = true) { date = timeUtil.dateFormat(date); this.myDate = timeUtil.getOtherMonth(this.myDate, \"nextMonth\"); this.$emit(\"changeMonth\", timeUtil.dateFormat(this.myDate)); this.axiosPost(\"/nannyCheckIn/findMonthList.n\", {date: this.myDate,joinWishListId: this.joinWishId,}, function (resData) { this.dateList = resData.list; }); if (isSelectedDay) { this.getList(this.myDate, date, isSelectedDay); } else { this.getList(this.myDate); } }, forMatArgs() { let markDate = this.markDate; let markDateMore = this.markDateMore; markDate = markDate.map(k => { return timeUtil.dateFormat(k); }); markDateMore = markDateMore.map(k => { k.date = timeUtil.dateFormat(k.date); return k; }); return [markDate, markDateMore]; }, getList(date, chooseDay, isSelectedDay = true) { const [markDate, markDateMore] = this.forMatArgs(); this.dateTop = `${date.getFullYear()}年${date.getMonth() + 1}月`; let arr = timeUtil.getMonthList(this.myDate); for (let i = 0; i < arr.length; i++) { let markClassName = \"\"; let k = arr[i]; k.chooseDay = false; const nowTime = k.date; const t = new Date(nowTime).getTime() / 1000; //看每一天的class for (const c of markDateMore) { if (c.date === nowTime) { markClassName = c.className || \"\"; } } //标记选中某些天 设置class k.markClassName = markClassName; k.isMark = markDate.indexOf(nowTime) > -1; //无法选中某天 k.dayHide = t < this.agoDayHide || t > this.futureDayHide; if (k.isToday) { this.$emit(\"isToday\", nowTime); } let flag = !k.dayHide && k.otherMonth === \"nowMonth\"; if (chooseDay && chooseDay === nowTime && flag) { this.$emit(\"choseDay\", nowTime); this.historyChose.push(nowTime); k.chooseDay = true; } else if ( this.historyChose[this.historyChose.length - 1] === nowTime && !chooseDay && flag ) { k.chooseDay = true; } } this.list = arr; } }, mounted() { this.getList(this.myDate); this.axiosPost(\"/nannyCheckIn/findMonthList.n\", {//业务,根据自己需要修改 joinWishListId: this.joinWishId, }, function (resData) { this.dateList = resData.list; }); }, watch: { markDate: { handler(val, oldVal) { this.getList(this.myDate); }, deep: true }, markDateMore: { handler(val, oldVal) { this.getList(this.myDate); }, deep: true }, agoDayHide: { handler(val, oldVal) { this.getList(this.myDate); }, deep: true }, futureDayHide: { handler(val, oldVal) { this.getList(this.myDate); }, deep: true }, sundayStart: { handler(val, oldVal) { this.intStart(); this.getList(this.myDate); }, deep: true }, joinWishId: {//监听这个是因为要切换工单,换数据 handler(val, oldVal) { this.axiosPost(\"/nannyCheckIn/findMonthList.n\", { joinWishListId: val, }, function (resData) { this.dateList = resData.list; }); }, deep: true } } }; </script>
calendar.js(日期工具类)
export default { // 当某月的天数 getDaysInOneMonth(date) { const year = date.getFullYear(); const month = date.getMonth() + 1; const d = new Date(year, month, 0); return d.getDate(); }, // 向前空几个 getMonthweek(date) { const year = date.getFullYear(); const month = date.getMonth() + 1; const dateFirstOne = new Date(year + \'/\' + month + \'/1\'); return this.sundayStart ? dateFirstOne.getDay() == 0 ? 7 : dateFirstOne.getDay() : dateFirstOne.getDay() == 0 ? 6 : dateFirstOne.getDay() - 1; }, /** * 获取当前日期上个月或者下个月 */ getOtherMonth(date, str = \'nextMonth\') { const timeArray = this.dateFormat(date).split(\'/\'); const year = timeArray[0]; const month = timeArray[1]; const day = timeArray[2]; let year2 = year; let month2; if (str === \'nextMonth\') { month2 = parseInt(month) + 1; if (month2 == 13) { year2 = parseInt(year2) + 1; month2 = 1; } } else { month2 = parseInt(month) - 1; if (month2 == 0) { year2 = parseInt(year2) - 1; month2 = 12; } } let day2 = day; const days2 = new Date(year2, month2, 0).getDate(); if (day2 > days2) { day2 = days2; } if (month2 < 10) { month2 = \'0\' + month2; } if (day2 < 10) { day2 = \'0\' + day2; } const t2 = year2 + \'/\' + month2 + \'/\' + day2; return new Date(t2); }, // 上个月末尾的一些日期 getLeftArr(date) { const arr = []; const leftNum = this.getMonthweek(date); const num = this.getDaysInOneMonth(this.getOtherMonth(date, \'preMonth\')) - leftNum + 1; const preDate = this.getOtherMonth(date, \'preMonth\'); // 上个月多少开始 for (let i = 0; i < leftNum; i++) { const nowTime = preDate.getFullYear() + \'/\' + (preDate.getMonth() + 1) + \'/\' + (num + i); arr.push({ id: num + i, date: nowTime, isToday: false, otherMonth: \'preMonth\', }); } return arr; }, // 下个月末尾的一些日期 getRightArr(date) { const arr = []; const nextDate = this.getOtherMonth(date, \'nextMonth\'); const leftLength = this.getDaysInOneMonth(date) + this.getMonthweek(date); const _length = 7 - leftLength % 7; for (let i = 0; i < _length; i++) { const nowTime = nextDate.getFullYear() + \'/\' + (nextDate.getMonth() + 1) + \'/\' + (i + 1); arr.push({ id: i + 1, date: nowTime, isToday: false, otherMonth: \'nextMonth\', }); } return arr; }, // format日期 dateFormat(date) { date = typeof date === \'string\' ? new Date(date.replace(/\\-/g, \'/\')) : date; return date.getFullYear() + \'/\' + (date.getMonth() + 1) + \'/\' + date.getDate(); }, // 获取某月的列表不包括上月和下月 getMonthListNoOther(date) { const arr = []; const num = this.getDaysInOneMonth(date); const year = date.getFullYear(); const month = date.getMonth() + 1; const toDay = this.dateFormat(new Date()); for (let i = 0; i < num; i++) { const nowTime = year + \'/\' + month + \'/\' + (i + 1); arr.push({ id: i + 1, date: nowTime, isToday: toDay === nowTime, otherMonth: \'nowMonth\', }); } return arr; }, // 获取某月的列表 用于渲染 getMonthList(date) { return [ ...this.getLeftArr(date), ...this.getMonthListNoOther(date), ...this.getRightArr(date) ]; }, // 默认是周一开始 sundayStart: false, };
然后引入到组件中
import nCalendar from \'./checkCalendar\' export default (Vue) => { Vue.component(\"nCalendar\", nCalendar); }
然后应用在页面中
<style lang=\"scss\" rel=\"stylesheet/scss\"> .nCalender { .detailDiv { margin: 20px 0; .imgDiv { img { width: 60px; height: 60px; } } .hourDiv { background-color: white; padding-top: 10px; .clockStyle { font-size: 16px; color: #4b90ed; } .hourText { font-size: 14px; margin-left: 5px; } } .stepDiv { .tagDiv { margin-top: 10px; } } } } </style> <template> <div class=\"nCalender\"> <navBar :showLeft=\"true\" :borderLine=true background=\"#f2f2f2\" title=\"考勤日历\"> <div @click=\"$router.push(\'/h5nAddCard\')\" slot=\"right\">补卡</div> </navBar> <van-field label=\"选择工单\" v-if=\"list.length>1\" :value=\"obj1!=null&&obj1.joinWishId!=null?obj1.joinWishId:null\"> <selectJoinTemp slot=\"input\" name=\"joinWishId\" name1=\"auditUserId\" v-model=\"obj1\" :isDefault=\"true\"/> </van-field> <!--日历--> <div class=\"CalendarDiv\" v-if=\"obj1&&obj1.joinWishId&&obj1.joinWishId>0\"> <nCalendar :joinWishId=\"obj1.joinWishId\" v-on:choseDay=\"clickDay\" v-on:changeMonth=\"changeDate\"/> </div> <div v-if=\"list.length==0\" class=\"detailDiv\" style=\"text-align: center;color: #bfbfbf\"> <div class=\"imgDiv\"> <img src=\"../img/rest.png\"/> </div> <div style=\"margin-top: 2%\"> 无合同 </div> </div> <!--当日详情--> <span></span> <div class=\"detailDiv\" v-if=\"obj!=null&&obj.id>0&&obj.recordDate&&new Date(obj.recordDate.replace(/-/g,\'/\'))<new Date()\"> <div class=\"hourDiv\"> <van-row> <van-col offset=\"1\"> <van-icon name=\"clock\" class=\"clockStyle\"/> </van-col> <van-col class=\"hourText\">工时共计:<span v-if=\"obj.totalHour!=null\">{{obj.totalHour}}小时</span> <span v-else>暂无</span></van-col> </van-row> </div> <div class=\"stepDiv\"> <van-steps direction=\"vertical\" :active=\"-1\"> <van-step> <div> 签到时间 <span v-if=\"obj.onDutyTime\">{{formatMinutes(obj.onDutyTime)}}</span> <span v-else>暂无</span>(上班时间:{{formatMinutes(obj.serverStartTime)}}) </div> <div class=\"tagDiv\"> <van-tag v-if=\"obj.onDutyTime&&!isLate(obj.onDutyTime,obj.serverStartTime)\" round type=\"primary\">正常 </van-tag> <van-tag v-else round type=\"warning\">迟到 </van-tag> </div> </van-step> <van-step> <div> 签退时间 <span v-if=\"obj.offDutyTime\">{{formatMinutes(obj.offDutyTime)}}</span> <span v-else>暂无</span>(下班时间:{{formatMinutes(obj.serverEndTime)}}) </div> <div class=\"tagDiv\"> <van-tag v-if=\"obj.offDutyTime&&isLate(obj.serverEndTime,obj.offDutyTime)\" round type=\"warning\">早退 </van-tag> <van-tag v-if=\"obj.offDutyTime&&!isLate(obj.serverEndTime,obj.offDutyTime)\" round type=\"primary\">正常 </van-tag> </div> </van-step> </van-steps> </div> </div> <div v-if=\"obj!=null&&obj.id>0&&!obj.offDutyTime&&!obj.onDutyTime\" class=\"detailDiv\" style=\"text-align: center;color: #bfbfbf\"> <div class=\"imgDiv\"> <img src=\"../img/rest.png\"/> </div> <div style=\"margin-top: 2%\"> 当天无打卡记录 </div> </div> </div> </template> <script> export default { name: \"nCalender\", data() { return { loginNannyUser: {}, loginGzhUser: {}, obj: {}, obj1: {}, list: [], dateTemp: null } }, methods: { isLate(str, str1) {//判断两个时分秒大小 return new Date((this.formatDates(new Date()) + \" \" + str).replace(/-/g, \'/\')) > new Date((this.formatDates(new Date()) + \" \" + str1).replace(/-/g, \'/\')); }, clickDay(data) {//选中某天 this.dateTemp = data this.axiosPost(\"/nannyCheckIn/findNowRecord.n\", { queryDate: data, id: this.obj1.joinWishId }, function (resData) { this.obj = resData.obj; }); }, changeDate(data) {//左右点击切换月份 console.log(data); }, }, mounted() { }, created() { let $this = this; this.getLoginAllUser(\"nanny\", {}, function () { $this.axiosPost(\"/joinWishList/findNannyCon.n\", {}, function (resData) { $this.list = resData.list; if (resData.list != null && resData.list.length != 0) { $this.$set($this.obj1, \"joinWishId\", resData.list[0].id); } $this.axiosPost(\"/nannyCheckIn/findNowRecord.n\", {id: $this.obj1.joinWishId}, function (resData) { $this.obj = resData.obj; }); }); }); }, watch: { \"obj1.joinWishId\": { handler(newObj, oldObj) { if (newObj != oldObj && newObj && newObj != null) { this.axiosPost(\"/nannyCheckIn/findNowRecord.n\", { queryDate: this.dateTemp, id: newObj }, function (resData) { this.obj = resData.obj; }); } }, deep: true }, } } </script>
差不多就是以上代码,直接复制了用,改一下ajax请求就行,需要扩展的就自己修改了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
© 版权声明
THE END
暂无评论内容