封裝就是要具備靈活性,樣式自適應,調用的時候傳入props就能夠變成本身想要的樣式。css
效果展現網址:https://1963331542.github.io/html
源代碼:vue
1 <template> 2 <div :style="mainBoxStyle" @mouseenter="setEnterFn()" @mouseleave="setLeaveFn()"> 3 <div :style="topLineStyle"> 4 <div 5 @click.stop="timeBoxShow=false;setNowTime(true)" 6 :style="[iptStyle,{float:'left'}]" 7 >{{curIptDate}}</div> 8 <div 9 @click="timeBoxShow=true;setTimeIpt(true)" 10 :style="[iptStyle,{float:'right'}]" 11 >{{curIptTime}}</div> 12 </div> 13 <div :style="timeBoxStyle" v-show="timeBoxShow"> 14 <div 15 :style="[timeAListStyle, 16 {paddingLeft:setWidth(12),width:setWidth(70)}]" 17 @mousewheel.stop="setIndex($event,1)" 18 v-on:DOMMouseScroll.stop="setIndex($event,1)" 19 > 20 <div 21 :style="[{zIndex:99,width:'100%', 22 height:setHeight(30),position:'absolute', 23 top:setHeight(60),left:setWidth(12),borderBottom:border, 24 borderTop:border}]" 25 ></div> 26 <div 27 v-for="(item,i) in hourArr" 28 @click="curShowHourIndex=(i-2)" 29 :style="[timeOneStyle,i==0? 30 {marginTop:setHeight((i-curShowHourIndex)*30), 31 transition:'margin-top 0.2s'}:{},(i-curShowHourIndex)==2? 32 {display:'flex',alignItems:'center'}:{}, 33 (i-curShowHourIndex)==5||(i-curShowHourIndex)==-1? 34 {color:'rgba(0,0,0,0)'}:{}]" 35 :key="i" 36 >{{item}}</div> 37 </div> 38 <div 39 :style="timeAListStyle" 40 @mousewheel.stop="setIndex($event,2)" 41 v-on:DOMMouseScroll.stop="setIndex($event,2)" 42 > 43 <div 44 :style="[{zIndex:99,width:'100%',height:setHeight(30), 45 position:'absolute',top:setHeight(60),left:0, 46 borderBottom:border,borderTop:border}]" 47 ></div> 48 <div 49 v-for="(item,i) in minArr" 50 @click="curShowMinIndex=(i-2)" 51 :style="[timeOneStyle,i==0? 52 {marginTop:setHeight((i-curShowMinIndex)*30),transition:'margin-top 0.2s'}:{}, 53 (i-curShowMinIndex)==2?{display:'flex',alignItems:'center'}:{}, 54 (i-curShowMinIndex)==5||(i-curShowMinIndex)==-1?{color:'rgba(0,0,0,0)'}:{}]" 55 :key="i" 56 >{{item}}</div> 57 </div> 58 <div 59 @mousewheel.stop="setIndex($event,3)" 60 v-on:DOMMouseScroll.stop="setIndex($event,3)" 61 :style="[timeAListStyle,{width:setWidth(30), 62 paddingRight:setWidth(12)}]" 63 > 64 <div 65 :style="[{zIndex:99,width:setWidth(30),paddingRight:setWidth(12), 66 height:setHeight(30),position:'absolute',top:setHeight(60),left:0, 67 borderBottom:border,borderTop:border}]" 68 ></div> 69 <div 70 v-for="(item,i) in secArr" 71 @click="curShowSecIndex=(i-2)" 72 :style="[timeOneStyle,i==0?{marginTop:setHeight((i-curShowSecIndex)*30), 73 transition:'margin-top 0.2s'}:{}, 74 (i-curShowSecIndex)==2?{display:'flex',alignItems:'center'}:{}, 75 (i-curShowSecIndex)==5||(i-curShowSecIndex)==-1?{color:'rgba(0,0,0,0)'}:{}]" 76 :key="i" 77 >{{item}}</div> 78 </div> 79 <div :style="{height:setHeight(33),float:'left',width:'100%'}"> 80 <div @click="timeBoxShow=false" :style="[bottomTimeBtnStyle,{color:'#1e90ff'}]">確認</div> 81 <div @click="timeBoxShow=false;curIptTime=''" :style="bottomTimeBtnStyle">取消</div> 82 </div> 83 </div> 84 <div :style="[onelineStyle,{height:setHeight(37)}]"> 85 <div 86 :style="[ 87 oneBtnStyle, 88 i<2?{float:'left'}:{float:'right'}, 89 { 90 height:setHeight(34) 91 } 92 ]" 93 v-for="(item,i) in [0,1,2,3]" 94 :key="i" 95 > 96 <div 97 :style="[ 98 sanjiaoStyle, 99 i<2?{float:'left'}: 100 {float:'right'} 101 ]" 102 :class="{'iconfont':true,'icon-zuoshuangjiantou':i==0, 103 'icon-icon-copy':i==1,'icon-icon':i==3,'icon-zuoshuangjiantou-copy':i==2}" 104 @click="i==0?setDate(curYear-1,curMonth): 105 i==1?setDate(curYear,curMonth-1): 106 i==3?setDate(curYear,curMonth+1):setDate(curYear+1,curMonth)" 107 ></div> 108 </div> 109 <div :style="titleStyle"> 110 <span>{{curYear}}</span>年 111 <span>{{curMonth}}</span>月 112 </div> 113 </div> 114 <div :style="[onelineStyle,{height:setHeight(34)}]"> 115 <div 116 v-for="(item,j) in [0,1,2,3,4,5,6]" 117 :key="j" 118 :style="[oneBtnStyle,{height:setHeight(34),fontSize:setHeight(16)}, 119 j==0?{clear:'both'}:{}]" 120 >{{weekList[j]}}</div> 121 </div> 122 <div 123 @mouseleave="curEnterDay=0" 124 :style="[onelineStyle,{height:setHeight(30*arr.length/7)}]" 125 > 126 <div 127 @mouseenter="i>=arr.indexOf(1)&&i<arr.lastIndexOf(1)?curEnterDay=item:''" 128 @click.stop="i>=arr.indexOf(1)&&i<arr.lastIndexOf(1) 129 ?clickFn(item):i<arr.indexOf(1) 130 ?switchMonthClick('-1',item):i>=arr.lastIndexOf(1) 131 ?switchMonthClick('+1',item):()=>{}" 132 :style="[ 133 oneBtnStyle, 134 {color:'#999999'}, 135 i>=arr.indexOf(1)&&i<arr.lastIndexOf(1)? 136 (item==curClickDay&&curMonth==curClickMonth&&curYear==curClickYear)? 137 selectStyle: 138 (item==curClickDay+1&&curMonth==curClickMonth&&curYear==curClickYear&&(i+1)%7==1) 139 ?{color:'#333333',clear:'both'}: 140 curEnterDay==item||(demoDate.getFullYear()==curYear 141 &&demoDate.getMonth()==curMonth-1 142 &&demoDate.getDate()==item)? 143 {color:'#1e90ff'}:{color:'#333333'} 144 :{}, 145 ]" 146 v-for="(item,i) in arr" 147 :key="i" 148 >{{item}}</div> 149 </div> 150 <div :style="[onelineStyle,{padding:0,paddingTop:setHeight(14),height:setHeight(54)}]"> 151 <div :style="bottomLineStyle"> 152 <div @click="emitDate()" :style="bottomBtnStyle">肯定</div> 153 <div 154 @click="setNowTime()" 155 :style="[bottomBtnStyle,{border:'none',color:'#1e90ff'}]" 156 >此刻</div> 157 </div> 158 </div> 159 </div> 160 </template> 161 162 <script> 163 import Vue from '@/main.js' 164 export default { 165 name: "calendar", 166 data() { 167 return { 168 mainBoxStyle: {}, 169 sanjiaoStyle: {}, 170 oneBtnStyle: {}, 171 onelineStyle: {}, 172 titleStyle: {}, 173 topLineStyle: {}, 174 bottomLineStyle: {}, 175 bottomBtnStyle: {}, 176 selectStyle: {}, 177 timeBoxStyle: {}, 178 bottomTimeBtnStyle: {}, 179 iptStyle: {}, 180 timeAListStyle: {}, 181 curYear: 0, 182 curMonth: 0, 183 curFirstWeek: "", 184 weekList: ["日", "一", "二", "三", "四", "五", "六"], 185 dateNumList: [], 186 arr: [], 187 curDate: {}, 188 curIptDate: "", 189 curIptTime: "", 190 curEnterDay: 0, 191 curClickDay: 0, 192 curClickMonth: 0, 193 curClickYear: 0, 194 curClickHour: "00", 195 curClickMin: "00", 196 curClickSec: "00", 197 demoDate: {}, 198 hourArr: [], 199 minArr: [], 200 secArr: [], 201 timeOneStyle: {}, 202 curShowHourIndex: 0, 203 curShowMinIndex: 0, 204 curShowSecIndex: 0, 205 timeBoxShow: false, 206 isLeaveCount:0, 207 isEnterCount:0, 208 }; 209 }, 210 created() { 211 for (var i = 0; i < 60; i++) { 212 if (i < 24) { 213 i < 10 ? this.hourArr.push("0" + i) : this.hourArr.push(i + ""); 214 } 215 i < 10 ? this.minArr.push("0" + i) : this.minArr.push(i + ""); 216 i < 10 ? this.secArr.push("0" + i) : this.secArr.push(i + ""); 217 } 218 this.curDate = new Date(); 219 if (this.value) { 220 this.setDate( 221 this.value.slice(0, 4), 222 this.value.slice(5, 7), 223 this.value.slice( 224 this.value.lastIndexOf(this.format[1]) + 1, 225 this.value.lastIndexOf(this.format[1]) + 3 226 ), 227 this.value.slice( 228 this.value.lastIndexOf(this.format[1]) + 4, 229 this.value.lastIndexOf(this.format[1]) + 6 230 ), 231 this.value.slice( 232 this.value.lastIndexOf(this.format[1]) + 7, 233 this.value.lastIndexOf(this.format[1]) + 9 234 ) 235 ); 236 this.clickFn(this.value.slice(8, 10) * 1); 237 } 238 var cw = (this.setWidth(33, true) - this.setHeight(28, true)).toFixed( 239 2 240 ); 241 var dw = (cw / 2).toFixed(2); 242 this.selectStyle = { 243 background: "#1e90ff", 244 width: this.setHeight(28), 245 height: this.setHeight(28), 246 margin: this.setHeight(1) + " 0", 247 marginLeft: dw + this.unit, 248 marginRight: cw - dw + this.unit, 249 float: "left", 250 color: "#fff", 251 borderRadius: "50%" 252 }; 253 this.demoDate = new Date(); 254 this.timeBoxStyle = { 255 width: this.setWidth(160), 256 height: this.setHeight(208), 257 background: this.background, 258 fontSize: this.fontSize + this.unit, 259 color: this.color, 260 border: this.border, 261 position: "absolute", 262 top: this.setHeight(46), 263 left: this.setWidth(130), 264 boxShadow: `0 0 ${this.setHeight(6)} rgba(0,0,0,0.3)` 265 }; 266 this.timeAListStyle = { 267 width: this.setWidth(58), 268 height: this.setHeight(161), 269 borderBottom: this.border, 270 overflow: "hidden", 271 // display:'flex', 272 // flexDirection:'column', 273 float: "left", 274 position: "relative", 275 marginTop: this.setHeight(10) 276 }; 277 this.timeOneStyle = { 278 width: "100%", 279 height: this.setHeight(30), 280 lineHeight: this.setHeight(30), 281 cursor: "pointer" 282 }; 283 this.bottomBtnStyle = { 284 width: this.setWidth(45), 285 height: this.setHeight(23), 286 border: this.border, 287 borderRadius: this.setHeight(3), 288 textAlign: "center", 289 lineHeight: this.setHeight(21), 290 float: "right", 291 marginRight: this.setHeight(4), 292 marginTop: this.setHeight(8), 293 marginBottom: this.setHeight(8), 294 cursor: "pointer" 295 }; 296 this.bottomTimeBtnStyle = { 297 width: this.setWidth(42), 298 height: this.setHeight(33), 299 textAlign: "center", 300 lineHeight: this.setHeight(33), 301 float: "right", 302 cursor: "pointer" 303 }; 304 this.bottomLineStyle = { 305 width: "100%", 306 height: this.setHeight(40), 307 borderTop: this.border 308 }; 309 this.iptStyle = { 310 width: this.setWidth(116), 311 height: this.setHeight(27), 312 border: this.border, 313 borderRadius: this.setHeight(3), 314 textAlign: "center", 315 lineHeight: this.setHeight(27), 316 marginTop: this.setHeight(9), 317 cursor: "pointer" 318 }; 319 this.topLineStyle = { 320 width: "100%", 321 height: this.setHeight(47), 322 borderBottom: this.border, 323 padding: "0 " + this.setWidth(7) 324 }; 325 this.mainBoxStyle = { 326 width: this.w + this.unit, 327 height: this.h, 328 float: "left", 329 background: this.background, 330 fontSize: this.fontSize + this.unit, 331 color: this.color, 332 border: this.border, 333 position: "relative", 334 boxShadow: `0 0 ${this.setHeight(6)} rgba(0,0,0,0.3)` 335 }; 336 this.oneBtnStyle = { 337 width: this.setWidth(33), 338 height: this.setHeight(30), 339 fontSize: this.fontSize + this.unit, 340 float: "left", 341 background: this.background, 342 display: "flex", 343 alignItems: "center", 344 justifyContent: "center", 345 cursor: "pointer" 346 }; 347 this.sanjiaoStyle = { 348 fontSize: this.setHeight(22) 349 }; 350 this.titleStyle = { 351 width: this.setWidth(96), 352 height: this.setHeight(32), 353 fontSize: this.setHeight(16), 354 lineHeight: this.setHeight(32), 355 float: "left", 356 textAlign: "center", 357 marginBottom: this.setHeight(5) 358 }; 359 this.onelineStyle = { 360 width: "100%", 361 paddingLeft: this.setWidth(12) 362 }; 363 this.init(); 364 }, 365 props: { 366 format: { 367 type: Array, 368 default: function() { 369 return ["-", " ", ":"]; 370 } 371 }, 372 fn: { 373 type: Function, 374 required: true 375 }, 376 value: { 377 type: String 378 }, 379 w: { 380 type: [Number, String], 381 default: 2.57 382 }, 383 h: { 384 type: [Number, String], 385 default: "auto" 386 }, 387 unit: { 388 type: String, 389 default: "rem" 390 }, 391 fontSize: { 392 type: [Number, String], 393 default: 0.14 394 }, 395 color: { 396 type: String, 397 default: "#333" 398 }, 399 border: { 400 type: String, 401 default: "0.01rem solid #cccccc" 402 }, 403 background: { 404 type: String, 405 default: "#fff" 406 } 407 }, 408 methods: { 409 setHeight(h, flag) { 410 if (flag) { 411 var height = 412 (this.unit == "rem" 413 ? (this.fontSize * ((h * 0.01) / 0.14)).toFixed(2) 414 : Math.round(this.fontSize * (h / 14))) * 1; 415 } else { 416 var height = 417 (this.unit == "rem" 418 ? (this.fontSize * ((h * 0.01) / 0.14)).toFixed(2) 419 : Math.round(this.fontSize * (h / 14))) + this.unit; 420 } 421 return height; 422 }, 423 setWidth(w, flag) { 424 if (flag) { 425 var Width = 426 (this.unit == "rem" 427 ? (this.w * ((w * 0.01) / 2.57)).toFixed(2) 428 : Math.round(this.w * (w / 257))) * 1; 429 } else { 430 var Width = 431 (this.unit == "rem" 432 ? (this.w * ((w * 0.01) / 2.57)).toFixed(2) 433 : Math.round(this.w * (w / 257))) + this.unit; 434 } 435 return Width; 436 }, 437 getMonthDayCount(year, month) { 438 var isLeapYear = false; 439 if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { 440 isLeapYear = true; 441 } 442 var dayCount = 0; 443 switch (month) { 444 case 0: 445 case 2: 446 case 4: 447 case 6: 448 case 7: 449 case 9: 450 case 11: 451 dayCount = 31; 452 break; 453 case 1: 454 if (isLeapYear) { 455 dayCount = 29; 456 } else { 457 dayCount = 28; 458 } 459 break; 460 default: 461 dayCount = 30; 462 break; 463 } 464 return dayCount; 465 }, 466 setDate(year, month, hour, min, sec) { 467 if (year) { 468 this.curDate.setFullYear(year * 1); 469 } 470 if (month) { 471 this.curDate.setMonth(month - 1); 472 } 473 if (hour) { 474 this.curDate.setHours(hour * 1); 475 } 476 if (min) { 477 this.curDate.setMinutes(min * 1); 478 } 479 if (sec) { 480 this.curDate.setSeconds(sec * 1); 481 } 482 this.init(); 483 }, 484 init() { 485 var activeDate = new Date(); 486 activeDate.setFullYear(this.curDate.getFullYear()); 487 activeDate.setMonth(this.curDate.getMonth()); 488 activeDate.setDate(this.curDate.getDate()); 489 activeDate.setHours(this.curDate.getHours()); 490 activeDate.setMinutes(this.curDate.getMinutes()); 491 activeDate.setSeconds(this.curDate.getSeconds()); 492 this.arr = []; 493 this.curYear = activeDate.getFullYear(); 494 this.curMonth = activeDate.getMonth() + 1; 495 if (this.value) { 496 this.curShowHourIndex = 497 this.hourArr.indexOf( 498 activeDate.getHours() < 10 499 ? "0" + activeDate.getHours() 500 : "" + activeDate.getHours() 501 ) - 2; 502 this.curShowMinIndex = 503 this.minArr.indexOf( 504 activeDate.getMinutes() < 10 505 ? "0" + activeDate.getMinutes() 506 : "" + activeDate.getMinutes() 507 ) - 2; 508 this.curShowSecIndex = 509 this.secArr.indexOf( 510 activeDate.getSeconds() < 10 511 ? "0" + activeDate.getSeconds() 512 : "" + activeDate.getSeconds() 513 ) - 2; 514 } 515 var len = this.getMonthDayCount( 516 activeDate.getFullYear(), 517 activeDate.getMonth() 518 ); 519 for (var i = 0; i < len; i++) { 520 this.arr.push(i + 1); 521 } 522 activeDate.setDate(0); 523 var lastMonthDayCount = this.getMonthDayCount( 524 activeDate.getFullYear(), 525 activeDate.getMonth() 526 ); 527 var weekIndex = activeDate.getDay(); 528 529 for (var i = 0; i < weekIndex + 1; i++) { 530 this.arr.unshift(lastMonthDayCount - i); 531 } 532 var len2 = this.arr.length; 533 for (var i = 0; i < 42 - len2; i++) { 534 this.arr.push(i + 1); 535 if (this.arr.length % 7 == 0) { 536 break; 537 } 538 } 539 }, 540 clickFn(item) { 541 this.timeBoxShow = false; 542 this.curClickDay = item; 543 this.curClickMonth = this.curMonth; 544 this.curClickYear = this.curYear; 545 this.curIptDate = 546 this.curClickYear + 547 this.format[0] + 548 (this.curClickMonth < 10 549 ? "0" + this.curClickMonth 550 : this.curClickMonth) + 551 this.format[0] + 552 (this.curClickDay < 10 553 ? "0" + this.curClickDay 554 : this.curClickDay); 555 }, 556 switchMonthClick(num, item) { 557 this.setDate(this.curYear, this.curMonth * 1 + num * 1); 558 setTimeout(() => { 559 this.clickFn(item); 560 }, 1); 561 }, 562 setNowTime(flag) { 563 if (!flag) { 564 this.setTimeIpt(true); 565 } 566 var nowDate = new Date(); 567 this.curClickYear = nowDate.getFullYear(); 568 this.curClickMonth = nowDate.getMonth() + 1; 569 this.curClickDay = nowDate.getDate(); 570 this.curIptDate = 571 this.curClickYear + 572 this.format[0] + 573 (this.curClickMonth < 10 574 ? "0" + this.curClickMonth 575 : this.curClickMonth) + 576 this.format[0] + 577 (this.curClickDay < 10 578 ? "0" + this.curClickDay 579 : this.curClickDay); 580 this.setDate(this.curClickYear, this.curClickMonth); 581 }, 582 setIndex(evt, num) { 583 if (evt.wheelDelta) { 584 if (evt.wheelDelta > 0) { 585 if (num == 1) { 586 if (this.curShowHourIndex < this.hourArr.length - 3) { 587 this.curShowHourIndex += 1; 588 } 589 } 590 if (num == 2) { 591 if (this.curShowMinIndex < this.minArr.length - 3) { 592 this.curShowMinIndex += 1; 593 } 594 } 595 if (num == 3) { 596 if (this.curShowSecIndex < this.secArr.length - 3) { 597 this.curShowSecIndex += 1; 598 } 599 } 600 } 601 if (evt.wheelDelta < 0) { 602 if (num == 1) { 603 if (this.curShowHourIndex > -2) { 604 this.curShowHourIndex -= 1; 605 } 606 } 607 if (num == 2) { 608 if (this.curShowMinIndex > -2) { 609 this.curShowMinIndex -= 1; 610 } 611 } 612 if (num == 3) { 613 if (this.curShowSecIndex > -2) { 614 this.curShowSecIndex -= 1; 615 } 616 } 617 } 618 } else if (evt.detail) { 619 if (evt.detail > 0) { 620 if (num == 1) { 621 if (this.curShowHourIndex < this.hourArr.length - 3) { 622 this.curShowHourIndex += 1; 623 } 624 } 625 if (num == 2) { 626 if (this.curShowMinIndex < this.minArr.length - 3) { 627 this.curShowMinIndex += 1; 628 } 629 } 630 if (num == 3) { 631 if (this.curShowSecIndex < this.secArr.length - 3) { 632 this.curShowSecIndex += 1; 633 } 634 } 635 } 636 if (evt.detail < 0) { 637 if (num == 1) { 638 if (this.curShowHourIndex > -2) { 639 this.curShowHourIndex -= 1; 640 } 641 } 642 if (num == 2) { 643 if (this.curShowMinIndex > -2) { 644 this.curShowMinIndex -= 1; 645 } 646 } 647 if (num == 3) { 648 if (this.curShowSecIndex > -2) { 649 this.curShowSecIndex -= 1; 650 } 651 } 652 } 653 } 654 }, 655 setTimeIpt(flag) { 656 this.timeBoxShow = true; 657 if (flag) { 658 var newDateTime = new Date(); 659 this.curShowHourIndex = newDateTime.getHours() - 2; 660 this.curShowMinIndex = newDateTime.getMinutes() - 2; 661 this.curShowSecIndex = newDateTime.getSeconds() - 2; 662 } 663 this.curClickHour = this.hourArr[this.curShowHourIndex * 1 + 2]; 664 this.curClickMin = this.minArr[this.curShowMinIndex * 1 + 2]; 665 this.curClickSec = this.secArr[this.curShowSecIndex * 1 + 2]; 666 this.curIptTime = 667 this.curClickHour + 668 this.format[2] + 669 this.curClickMin + 670 this.format[2] + 671 this.curClickSec; 672 }, 673 emitDate() { 674 if (this.curIptDate && this.curIptTime) { 675 var valueFB = 676 this.curIptDate + this.format[1] + this.curIptTime; 677 this.fn(false); 678 this.$emit("input", valueFB); 679 } 680 }, 681 setLeaveFn() { 682 console.log('LeaveAdd') 683 this.addEvent(document.body,'click',this.abc) 684 }, 685 setEnterFn(){ 686 console.log('enterRemove') 687 this.removeEvent(document.body,'click',this.abc) 688 }, 689 abc(){ 690 this.fn(false) 691 this.removeEvent(document.body,'click',this.abc) 692 }, 693 addEvent(element, type, callback) { 694 if (element.addEventListener) { 695 element.addEventListener(type, callback, false); 696 } else if (element.attachEvent) { 697 element.attachEvent("on" + type, callback); 698 } else { 699 element["on" + type] = callback; 700 } 701 }, 702 removeEvent(ele,str,fn) { 703 if(ele.removeEventListener){ 704 ele.removeEventListener(str,fn); 705 }else if(ele.detachEvent){ 706 ele.detachEvent("on"+str,fn); 707 }else{ 708 ele["on"+str] = null; 709 } 710 } 711 }, 712 watch: { 713 curShowHourIndex(newVal, oldVal) { 714 this.setTimeIpt(); 715 }, 716 curShowMinIndex(newVal, oldVal) { 717 this.setTimeIpt(); 718 }, 719 curShowSecIndex(newVal, oldVal) { 720 this.setTimeIpt(); 721 }, 722 }, 723 mounted() { 724 this.$nextTick(function(){ 725 this.setFont() 726 }) 727 } 728 }; 729 </script> 730 731 <style scoped> 732 @import "https://at.alicdn.com/t/font_1043142_ucomoekqib.css"; 733 span { 734 display: inline-block; 735 } 736 .clear-fix:after { 737 content: "."; 738 clear: both; 739 display: block; 740 height: 0; 741 overflow: hidden; 742 visibility: hidden; 743 } 744 div { 745 -moz-user-select: none; 746 -o-user-select: none; 747 -khtml-user-select: none; 748 -webkit-user-select: none; 749 -ms-user-select: none; 750 user-select: none; 751 } 752 h1 { 753 flex-direction: column; 754 justify-content: flex-end; 755 } 756 </style>
--------------------------------------------------------------------------------------------------------------------------------------------------------git
1.建一個vue文件,打出一個 < 而後按tab鍵 自動建立vue的模板 首先在script標籤裏寫好name和props屬性github
props寫成校驗寫法,這裏我先定義了寬度w,高度h,單位rem,字體大小fontSize,字體顏色color,邊框border,背景顏色background,這些都是基本的組件封裝須要的props。如圖:web
這些props我都給它設置了一個默認值,當調用時不傳其中的某個參數就是默認的值,傳的話就是指定值;ide
而後定義交互的props: v-model須要的props:value v-model綁定的是顯示在父組件某個容器裏的值 顯示的日期格式化單位format 控制顯隱的點擊函數fn。如圖:函數
類型爲Array或者Object的props設置默認值須要用回調函數返回。字體
-------------------------------------------------------------------------------------------------------------------------------------------------flex
2.props定義好後就開始寫結構和樣式,這裏的樣式不能寫在style標籤裏面,須要用:style動態添加到標籤上面。
先寫data定義好幾個基礎的樣式變量。如圖:
接着在methods裏面寫兩個設置寬度樣式setWidth和高度樣式setHeight的方法。如圖:
setHeight與setWidth這兩個方法的第一個參數爲設置的像素大小(即設計圖量的多少px就傳多少,不帶單位),第二個參數可選,傳入true時返回一個純數字,不傳時返回一個帶單位的值
這裏我用了三元運算符,後面將會大量用到三元運算符(有嵌套用法)。this.w與this.fontSize即傳入的props。
this.w*(w/257)與this.fontSize*(h/14) 這裏的w / 257就是你要設置的寬相對於設計圖的最外層大盒子的寬的佔比。h/14就是設置的高相對於字體大小的佔比。
這裏不推薦用h / this.h 由於這裏的組件高度須要自適應。
-------------------------------------------------------------------------------------------------------------------------------
3.template裏面建立好基本結構 。如圖:
接着在created裏面初始化樣式 。如圖:
上面的代碼可能就是最後的this.selectStyle有點很差理解
這裏的cw就是用按鈕的實際的寬度去減選中時的高度。由於選中的時候寬度須要寫成和高度同樣的才能成爲一個圓形。
這時就須要設置選中的按鈕左右的margin。由於cw 有多是奇數,因此除以2的時候再四捨五入就不是平均值了。
因此margin-right就是用cw減去margin-left的值,避免盒子被擠到下一行。
-------------------------------------------------------------------------------------------------------
4.邏輯部分=>建立結構裏須要顯示的數據。如圖:
在template裏將數據渲染到標籤上。如圖:
接着在methods裏面寫一個初始化方法 init :
這個方法用來渲染頁面的日期數據,這裏須要寫一個獲取指定年份和月份所對應的天數。
在methods裏面再定義一個方法getMonthDayCount。如圖:
渲染日曆init方法,如圖:
init方法寫好後在created鉤子函數裏最後調用一下 this.init()
調用這個方法寫完後頁面的初始數據就算完成了,這時頁面仍是有問題的,有許多地方部分樣式須要重寫,
因此下面就是如何重寫部分樣式。如圖:
class的動態添加也能夠給指定的項添加對應的class類名。如圖:
後面的一些樣式微調就不一一截圖了,當樣式微調寫好後,組件應該已經能夠看到效果了,接下來寫年份月份的切換效果,
這裏須要再在methods裏面定義一個setDate方法,用於設置當前時間對象,從新渲染日曆。如圖:
next:給切換的圖標寫上點擊事件。如圖:
這時鼠標點擊切換年月份已經沒有問題了。
而後給每個日期寫一個點擊事件函數clickFn。如圖:
------------------------------------------------------------------------未完待續------------------------------------------------------------------