制作日历组件,点击出来一个弹窗
实现效果如下图:点击弹出弹窗(弹窗用iview的modal组件),在输入框填写并存储(用了一下localstorage来存储),这个组件参考了条链接,原文存储的功能链接,还有以为博主的日历实现后续找到补上。按需选取吧代码部分。
代码贴上
CSS
1 .calender { 2 text-align: center; 3 min-width: 280px; 4 /* height: 400px; */ 5 overflow: hidden; 6 } 7 .calender-title-wrapper { 8 height: 30px; 9 line-height: 30px; 10 } 11 12 .calender-title { 13 display: -moz-box; 14 display: -webkit-box; 15 display: -ms-flexbox; 16 display: -webkit-flex; 17 display: flex; 18 display: flex; 19 margin: 0 auto; 20 width: 280px; 21 } 22 23 .calender-arrow-item { 24 flex: 0 0 30px; 25 cursor: pointer; 26 } 27 .calender-arrow-item.left1,.calender-arrow-item.left2{float: left;} 28 .calender-arrow-item.right1,.calender-arrow-item.right2{float: right;} 29 30 .calender-arrow-item.left1:after { 31 content: "\00AB "; 32 display: inline; 33 } 34 .calender-arrow-item.left2:after { 35 content: "\00AB "; 36 display: inline; 37 } 38 .calender-arrow-item.right1:after { 39 content: "\00BB"; 40 display: inline; 41 } 42 .calender-arrow-item.right2:after { 43 content: "\00BB"; 44 display: inline; 45 } 46 .calender-Date-text { 47 flex: 1; 48 color: #424242; 49 font-size: 14px; 50 display: inline-block; 51 } 52 53 .calender-days-wrapper { 54 display: flex; 55 height: 30px; 56 line-height: 30px; 57 margin-bottom: 11px; 58 } 59 60 .calender-days { 61 flex: 1; 62 color: #a7a7a7; 63 font-size: 14px; 64 float: left; 65 width: 14.285%; 66 } 67 68 .calender-item-wrapper { 69 position: relative; 70 float: left; 71 width: 14.285%; 72 height: 30px; 73 line-height: 30px; 74 color: #686868; 75 cursor: pointer; 76 } 77 .calender-item-wrapper.active { 78 background-color: #03a9f44f; 79 } 80 .active { 81 background-color: #03a9f44f; 82 } 83 .tem-wrapper { 84 position: absolute; 85 left: 50%; 86 height: 10px; 87 width: 30px; 88 transform: translate3d(-50%, 35px, 0); 89 font-size: 0; 90 } 91 92 .temp { 93 position: relative; 94 display: inline-block; 95 line-height: 10px; 96 width: 6px; 97 height: 6px; 98 background: #4fff41; 99 border-radius: 3px; 100 top: -20px; 101 margin: 0 2px; 102 } 103 104 .calender-item { 105 position: absolute; 106 left: calc(50% - 15px); 107 top: calc(50% - 15px); 108 height: 30px; 109 width: 30px; 110 border-radius: 20px; 111 line-height: 30px; 112 } 113 114 .calender-item:hover { 115 background: #2a81e2; 116 } 117 .no-current-day .calender-item { 118 color: #dcdcdc; 119 } 120 .currentDay .calender-item { 121 color: #ffffff; 122 background: #2a81e2; 123 } 124 .calender-item { 125 /* background :#FFC912; */ 126 } 127 .calender-item.active { 128 color: #ffffff; 129 } 130 .calender-item { 131 /* background: #FFC912; */ 132 } 133 .calender-mask-wrapper { 134 height: 37px; 135 } 136 137 .calender-mask-item { 138 height: 37px; 139 line-height: 37px; 140 width: 25%; 141 float: left; 142 } 143 144 .tem { 145 margin-right: 3px; 146 display: inline-block; 147 height: 8px; 148 width: 8px; 149 border-radius: 4px; 150 } 151 152 .text { 153 font-size: 14px; 154 } 155 156 button.ivu-btn.ivu-btn-save{ 157 border-color: #1E9FFF; 158 background-color: #1E9FFF; 159 color: #fff; 160 } 161 button.ivu-btn.ivu-btn-save:hover{ 162 opacity: .9; 163 text-decoration: none; 164 } 165 166 .ivu-select-dropdown{ 167 z-index: 1001; 168 }
结构部分:
1 <div class="calender"> 2 <div class="calender-title-wrapper"> 3 <div class="calender-title"> 4 <div class="calender-arrow-item left2" v-if="false"></div> 5 <div class="calender-arrow-item left1" @click="month--"></div> 6 <div class="calender-Date-text">{{year}}年{{month}}月</div> 7 <div class="calender-arrow-item right1" @click="month++"></div> 8 <div class="calender-arrow-item right2" v-if="false"></div> 9 </div> 10 </div> 11 <div class="calender-content-wrapper"> 12 <div class="calender-days-wrapper"> 13 <div class="calender-days">日</div> 14 <div class="calender-days">一</div> 15 <div class="calender-days">二</div> 16 <div class="calender-days">三</div> 17 <div class="calender-days">四</div> 18 <div class="calender-days">五</div> 19 <div class="calender-days">六</div> 20 </div> 21 <div class="calender-content"> 22 <div class="calender-item-wrapper" v-for="item in daysArr" :class="{'no-current-day':item.month!=month, 23 active:item === clickItemObj, 24 currentDay:item.day===_CurrentDate.day&& 25 item.month===_CurrentDate.month&& 26 item.year===_CurrentDate.year}" @click="_clickDaysItem(item)"> 27 <div class="calender-item">{{item.day}}</div> 28 <div class="tem-wrapper"> 29 <span class="temp" v-for="d in markArr" v-if="_visibleTemp(d,item)"></span> 30 </div> 31 </div> 32 </div> 33 </div> 34 </div> 35 <Modal title="add new note" v-model="noteSome" class-name="vertical-center-modal" 36 footerHide class="memo"> 37 <Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="80"> 38 <FormItem label="theme:" prop="theme"> 39 <Input v-model="formValidate.theme" placeholder="please send the theme..."></Input> 40 </FormItem> 41 <FormItem label="currentTime:"> 42 <p>{{currentTime}}</p> 43 </FormItem> 44 <FormItem label="reminderTime:" prop="pickTime"> 45 <DatePicker type="datetime" placeholder="please choose the time" v-model="formValidate.pickTime"></DatePicker> 46 </FormItem> 47 <FormItem label="content:" prop="desc"> 48 <Input id="text_book" v-model="formValidate.desc" type="textarea" :autosize="{minRows: 2,maxRows: 5}" 49 placeholder="please send the content..."></Input> 50 </FormItem> 51 <div class="ivu-modal-footer"> 52 <slot name="footer"> 53 <button class="ivu-btn ivu-btn-save" @click.stop.prevent="handleSubmit(dateValue,'formValidate')">save</button> 54 <button class="ivu-btn ivu-btn-info" @click.stop.prevent="handleReset('formValidate')">delete</button> 55 <button class="ivu-btn ivu-btn-info" @click.stop.prevent="clickCancel">cancel</button> 56 </slot> 57 </div> 58 </Form> 59 </Modal> 60 <Modal v-model="confirmDele" width="360" class-name="vertical-center-modal"> 61 <p slot="header" style="color:#f60;text-align:center"> 62 <span>conform cancel</span> 63 </p> 64 <div style="text-align:center"> 65 <p>please confirm?</p> 66 </div> 67 <div slot="footer"> 68 <Button type="error" size="large" @click="del('formValidate')">cancel</Button> 69 </div> 70 </Modal>
逻辑部分
1 data() { 2 return { 3 day: "", 4 month: "", 5 year: "", 6 currentDays: "", 7 daysArr: [], 8 clickItemObj: {}, 9 noteSome: false, 10 formValidate: { 11 theme: "", 12 pickTime: "", 13 desc: "" 14 }, 15 ruleValidate: { 16 theme: [{ message: "please send theme", trigger: "blur" }], 17 pickTime: [{ type: "date", message: "choose time", trigger: "change" }], 18 desc: [{ message: "send content", trigger: "blur", value: "" }] 19 }, 20 dateValue: "", 21 markJson: {}, 22 dataAll: {}, 23 markArr: [], 24 theUserCode: "", 25 currentTime: this.formatDateTime(new Date()), 26 confirmDele: false 27 }; 28 }, 29 created() { 30 this.theUserCode = store.state.sys.userCode; 31 this.getMemo(); 32 }, 33 mounted() { 34 this._getCurrentDate(); 35 }, 36 methods: { 37 // 获取当前时间 38 formatDateTime(date) { 39 var y = date.getFullYear(); 40 var m = date.getMonth() + 1; 41 m = m < 10 ? "0" + m : m; 42 var d = date.getDate(); 43 d = d < 10 ? "0" + d : d; 44 var h = date.getHours(); 45 h = h < 10 ? "0" + h : h; 46 var minute = date.getMinutes(); 47 minute = minute < 10 ? "0" + minute : minute; 48 var second = date.getSeconds(); 49 second = second < 10 ? "0" + second : second; 50 return y + "-" + m + "-" + d + " " + h + ":" + minute + ":" + second; 51 }, 52 //点击日期 53 _clickDaysItem(item) { 54 this.dateValue = item.year + "/" + item.month + "/" + item.day; 55 let data = { year: item.year, month: item.month, date: item.day }; 56 this.dataAll = { year: item.year, month: item.month, date: item.day }; 57 this.$refs["formValidate"].resetFields(); 58 this.currentTime = this.formatDateTime(new Date()); 59 60 for (let i = 0; i < this.markArr.length; i++) { 61 if (this.markArr[i] == this.dateValue) { 62 this.formValidate.theme = this.markJson[this.dateValue][0].theme; 63 this.formValidate.pickTime = this.markJson[ 64 this.dateValue 65 ][2].pickTime; 66 this.formValidate.desc = this.markJson[this.dateValue][3].desc; 67 this.currentTime = this.markJson[this.dateValue][1].saveTime; 68 } 69 } 70 71 if (this.clickItemObj === item) { 72 this.clickItemObj = {}; 73 } else { 74 this.clickItemObj = item; 75 } 76 77 //非当前月份跳转 78 if (item.month != this.month) { 79 this.month = item.month; 80 } 81 //传入事件筛选回返 82 this.openPop(); 83 //传入当前时间 84 }, 85 // 获取已存的日期 86 getMemo() { 87 let theMemo = JSON.parse( 88 localStorage.getItem(this.theUserCode + "dateJson") 89 ); 90 if (theMemo != null) { 91 this.markJson = theMemo; 92 } 93 this.markArr = []; 94 for (var a in this.markJson) { 95 this.markArr.push(a); 96 } 97 }, 98 //调用弹出层方法 99 openPop() { 100 this.noteSome = true; 101 }, 102 //是否显示mark 103 _visibleTemp(d, item) { 104 // 展示是否标记 105 let dateStr = `${item.year}/${item.month}/${item.day}`; 106 if (d == dateStr) { 107 return d.includes(dateStr); 108 } 109 }, 110 //获取月份天数 111 _getDaysForMonth(year, month, type) { 112 let temp = new Date(year, month, type); 113 let day = new Date(temp.getTime() - 864e5).getDate(); 114 this.currentDays = day; 115 this._getFirstDaysForMonth(this.year, this.month); 116 }, 117 //获取当前日期 118 _getCurrentDate() { 119 let date = new Date(); 120 this.day = date.getDate(); 121 this.month = date.getMonth() + 1; 122 this.year = date.getFullYear(); 123 this._getDaysForMonth(this.year, this.month, 1); 124 }, 125 //获取切换页月份第一天是周几与最后一天并获取月前与月后填补数组 126 _getFirstDaysForMonth(year, month) { 127 let weekdays = new Date(`${year}/${month}/01`).getDay(); 128 let beforeMonthDaysArr = []; 129 let currentMonthDaysArr = []; 130 let afterMonthDaysArr = []; 131 //获取上一月总天数 132 if (month) { 133 let temp = new Date(year, month - 1, 1); 134 let day = new Date(temp.getTime() - 864e5).getDate(); 135 for (let i = 0; i < day; i++) { 136 beforeMonthDaysArr.push({ 137 year: year, 138 month: month - 1, 139 day: i + 1 140 }); 141 } 142 beforeMonthDaysArr.splice(0, beforeMonthDaysArr.length - weekdays); 143 } else { 144 //12月 145 } 146 //获取当前月总天数 147 let temp = new Date(year, month, 1); 148 let day = new Date(temp.getTime() - 864e5).getDate(); 149 let afterWeekdays = new Date(`${year}/${month}/${day}`).getDay(); 150 for (let i = 0; i < day; i++) { 151 currentMonthDaysArr.push({ 152 year: year, 153 month: month, 154 day: i + 1 155 }); 156 } 157 158 if ( 159 beforeMonthDaysArr.length + 160 currentMonthDaysArr.length + 161 6 - 162 afterWeekdays === 163 35 164 ) { 165 for (let i = 0; i < 13 - afterWeekdays; i++) { 166 afterMonthDaysArr.push({ 167 year: year, 168 month: month + 1, 169 day: i + 1 170 }); 171 } 172 } else { 173 for (let i = 0; i < 6 - afterWeekdays; i++) { 174 afterMonthDaysArr.push({ 175 year: year, 176 month: month + 1, 177 day: i + 1 178 }); 179 } 180 } 181 this.daysArr = [ 182 ...beforeMonthDaysArr, 183 ...currentMonthDaysArr, 184 ...afterMonthDaysArr 185 ]; 186 }, 187 //保存按钮方法 188 handleSubmit(obj_date, name) { 189 this.$refs[name].validate(valid => { 190 // 判断是否为空 191 if (valid && this.theUserCode != undefined && this.theUserCode != "") { 192 this.chose_moban(this.dateValue, this.markJson); 193 this.noteSome = false; 194 } else { 195 // 为空 196 // this.$Message.error('Fail!'); 197 } 198 }); 199 }, 200 // 存储 201 chose_moban(obj_date, markJson) { 202 if (this.formValidate.desc == "") { 203 delete markJson.obj_date; 204 } else { 205 markJson[obj_date] = [ 206 { theme: this.formValidate.theme }, 207 { saveTime: this.currentTime }, 208 { pickTime: this.formatDateTime(this.formValidate.pickTime) }, 209 { desc: this.formValidate.desc } 210 ]; 211 } 212 this.noteSome = false; 213 localStorage.setItem( 214 this.theUserCode + "dateJson", 215 JSON.stringify(markJson) 216 ); 217 this.getMemo(); 218 }, 219 handleReset(name) { 220 // 撤销 221 this.confirmDele = true; 222 }, 223 del(name) { 224 this.$refs[name].resetFields(); 225 this.chexiao(this.dateValue, this.markJson); 226 this.confirmDele = false; 227 this.chose_moban(this.dateValue, this.markJson); 228 this.getMemo(); 229 }, 230 chexiao(obj_date, markJson) { 231 //删除指定日期标注 232 delete markJson[obj_date]; 233 }, 234 clickCancel() { 235 this.noteSome = false; 236 }, 237 _choseMoban(obj_date, markJson) {} 238 }, 239 watch: { 240 month() { 241 if (this.month === 0) { 242 this.month = 12; 243 this.year--; 244 } 245 if (this.month === 13) { 246 this.month = 1; 247 this.year++; 248 } 249 this._getDaysForMonth(this.year, this.month, 1); 250 } 251 }, 252 computed: { 253 _CurrentDate() { 254 let date = new Date(); 255 let { day, month, year } = { 256 day: date.getDate(), 257 month: date.getMonth() + 1, 258 year: date.getFullYear() 259 }; 260 return { day, month, year }; 261 } 262 }