Open openks opened 6 years ago
定制日历这种功能做过N次了,每次都是在需要的时候重新写,这次记录下,便于以后用到时查找
需求: 用日历格式显示前7天或者前30天的每一天是否有数据传输, 如果有则用一种颜色表示 状态A 如果无则用另一种颜色显示 状态B 今日之后的日历灰掉 状态C 统计数据之前的日期正常显示 状态D
从需求的角度讲可以也可以简化为2种状态,一种是有数据状态A,一种是其他状态B
实现方案: 本来想的是根据当前日期判断前7天或前30天是否跨月 如果跨月显示两个月的日历 如果不跨月只显示一个月的日历即可 再根据数据判断如果有记录则显示状态,其他不做处理, 但是根据需求明显不止两种状态 虽说状态增多但主要逻辑依然正确,只不过要显示的状态多了点
关于跨月简单举例, 如今天是2018年1月5号则前7天和前30天均跨月 如今天是2018年1月31号则前7天和前30天均不跨月 如今天是2018年1月9号则前7天不跨月但前30天跨月 有且只有这3种情况
组件源代码如下:
<!-- cleader.vue --> <template lang="html"> <div class="calanderWp" :class="{'hide':!dialogVisible}"> <div class="calander prev" v-if="JSON.stringify(dayPreInfo).length!==2"> <div class="cal-title">{{dayPreInfo.date}}</div> <ul class="cal-ul"> <li class="cal-li" v-for="it in ['日','一','二','三','四','五','六',]">{{it}}</li> <li class="cal-li" v-for="emp in dayPreInfo.weekone"></li> <li class="cal-li" :class="[showData(getDate(dayPreInfo.year,dayPreInfo.month,em))]" :date="getDate(dayPreInfo.year,dayPreInfo.month,em)" v-for="em in dayPreInfo.days">{{em}}</li> </ul> <div class="status"> <span class="item2"><span class="tran"></span><span>已传输</span></span> <span class="item1"><span class="untran"></span><span>未传输</span></span> </div> </div> <div class="calander"> <div class="cal-title">{{dayInfo.date}}</div> <ul class="cal-ul"> <li class="cal-li" v-for="it in ['日','一','二','三','四','五','六',]">{{it}}</li> <li class="cal-li" v-for="emp in dayInfo.weekone"></li> <li class="cal-li" :class="[showData(getDate(dayInfo.year,dayInfo.month,em))]" :date="getDate(dayInfo.year,dayInfo.month,em)" v-for="em in dayInfo.days">{{em}}</li> </ul> <div class="status"> <span class="item2"><span class="tran"></span><span>已传输</span></span> <span class="item1"><span class="untran"></span><span>未传输</span></span> </div> </div> </div> </template> <script> export default { props: { visible: { type: Boolean, default: true }, period: { type: Number, default: 7 }, dataList: { type: Array, default: function () { return [] } } }, data () { return { dataFromDate: '', // 数据开始时间 dayPreInfo: {}, // 上个月数据 dayInfo: {} // 本月信息 用于绘制日历 } }, computed: { dialogVisible: { set (newValue) { this.$emit('update:visible', newValue) }, get () { return this.visible } } }, methods: { getPrevData (date) { return this.moment(this.dataFromDate).diff(this.moment(date)) > 0 }, showData (date) { let t = [ { 'date': '2018-01-20' }, { 'date': '2018-01-27' }, { 'date': '2018-01-29' }, { 'date': '2018-01-30' }, { 'date': '2018-01-31' }, { 'date': '2018-02-01' }] if (this.dataList.length > 0) { t = this.dataList } let tmp = t.map(ele => { return ele.date }) let ret = '' let dfdm = this.moment(this.dataFromDate) let dm = this.moment(date) let tdm = this.moment() console.log('this.dataFromDate', this.dataFromDate) console.log('date', date) if (dfdm.diff(dm) > 0) { ret = 'prev' } else if (tmp.includes(date)) { ret = 'date' } else if (dm.diff(tdm) > 0) { ret = 'next' } else { ret = 'no-date' } return ret }, getDate (year, month, day) { return year + '-' + month + '-' + (day < 10 ? '0' + day : day) }, dealTimes () { // console.log('ref', this.$refs.inpa.value) let t = this.period let dinfo = this.dayInfo this.dataFromDate = this.moment().subtract((parseInt(t, 10) + 1), 'd') if (dinfo.day < t) { let d = new Date(dinfo.year, dinfo.month - 2, 1) this.dayPreInfo = this.getDayInfo(d) // console.log('获取2个月数据', this.dayPreInfo, d) } else { this.dayPreInfo = {} // console.log('获取1个月数据') } }, /** * 获取该日是周几 0-6,该月共几天,该日是几号 * @method getDayInfo * @param {[Date]} date [description] * @return {Object} [description] * @datetime 2018-02-02T14:31:10+080 */ getDayInfo: function (date) { var inDate = date || new Date() var tmp = {} // 0-6分别表示周日到周六 tmp.week = inDate.getDay() // 该日所在月天数 tmp.days = this.getDays(inDate.getFullYear(), inDate.getMonth()) // 该日日期 tmp.day = inDate.getDate() // 该月1号是周几 tmp.weekone = new Date(inDate.getFullYear(), inDate.getMonth(), 1) .getDay() tmp.date = this.moment(inDate) .format('YYYY-MM') tmp.year = inDate.getFullYear() let m = inDate.getMonth() + 1 tmp.month = m < 10 ? '0' + m : m return tmp }, /** * 根据年份及月份获取该月天数 * @param {[Number]} yeara 4位年份 * @param {[Number]} montha 当前月份减一值 * @return {Number} 当前月份总天数 */ getDays: function (yeara, montha) { // console.log("year-month:", yeara, montha); var td = new Date() var month = montha var days = 0 var big = [1, 3, 5, 7, 8, 10, 12] var year = yeara || td.getFullYear() // montha 可能为0 所以不能用或运算符 if (typeof (month) === 'undefined') { month = td.getMonth() } month = month + 1 // console.log("year-month2:", year, month); if (month === 2) { if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) { days = 29 } else { days = 28 } } else { if (big.indexOf(month) > -1) { days = 31 } else { days = 30 } } // console.log("year-month3:", days); return days } }, mounted () { this.dayInfo = this.getDayInfo() this.dealTimes() } } </script> <style lang="less"> .calanderWp { &.hide { display: none } .calander { width: 224px; padding: 20px 20px 10px; background: #fff; float: left; &.prev { border-right: 1px solid #e3e3e3; } .cal-title { text-align: center; height: 30px; font-size: 14px; } .cal-ul { overflow: hidden; margin: 0; padding: 0; background: #fff; .cal-li { float: left; display: block; width: 30px; height: 30px; line-height: 30px; text-align: center; margin: 1px; &.today{ background-color: #eeeeee; } &.prev { background-color: #FFF; } &.no-date { background-color: #D3DCE6; } &.date { background-color: #FBBD00; } &.next { color: #C0CCDA; } } } .status { display: flex; justify-content: center; padding: 8px 0 0; .untran,.tran{ display: flex; width: 16px; height: 12px; margin-right: 5px; background-color: #D3DCE6; } .item1,.item2{ display: flex; align-items: center; } .item2{ margin-right: 10px; } .tran{ background-color: #F6CE00; } } } } </style>
使用方法
<div class="wpper"> <el-button type="primary" size="small" class="m-x-r" @click="testBtnClick('showDialog6')">测试数据功能</el-button> <test-info :visible.sync="showDialog6" :period="30" class="test1"></test-info> </div> <script> import testInfo from '../cleader.vue' export default { components: { 'test-info': testInfo }, data () { return { showDialog6: false } }, methods: { testBtnClick (item) { this[item] = !this[item] } } } </script>
定制日历这种功能做过N次了,每次都是在需要的时候重新写,这次记录下,便于以后用到时查找
需求:
用日历格式显示前7天或者前30天的每一天是否有数据传输,
如果有则用一种颜色表示 状态A
如果无则用另一种颜色显示 状态B
今日之后的日历灰掉 状态C
统计数据之前的日期正常显示 状态D
实现方案:
本来想的是根据当前日期判断前7天或前30天是否跨月
如果跨月显示两个月的日历
如果不跨月只显示一个月的日历即可
再根据数据判断如果有记录则显示状态,其他不做处理,
但是根据需求明显不止两种状态
虽说状态增多但主要逻辑依然正确,只不过要显示的状态多了点
组件源代码如下:
使用方法