封装就是要具有灵活性,样式自适应,调用的时候传入props就可以变成自己想要的样式。

效果展示网址:https://1963331542.github.io/

源代码:

  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>

日历组件源代码

--------------------------------------------------------------------------------------------------------------------------------------------------------

1.建一个vue文件,打出一个 <  然后按tab键  自动创建vue的模板  首先在script标签里写好name和props属性

props写成校验写法,这里我先定义了宽度w,高度h,单位rem,字体大小fontSize,字体颜色color,边框border,背景颜色background,这些都是基本的组件封装需要的props。如图:

这些props我都给它设置了一个默认值,当调用时不传其中的某个参数就是默认的值,传的话就是指定值;

然后定义交互的props:   v-model需要的props:value   v-model绑定的是显示在父组件某个容器里的值   显示的日期格式化单位format  控制显隐的点击函数fn。如图:

类型为Array或者Object的props设置默认值需要用回调函数返回。

-------------------------------------------------------------------------------------------------------------------------------------------------

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。如图:

------------------------------------------------------------------------未完待续------------------------------------------------------------------

Vue文件封装日历组件的更多相关文章

  1. Vue中封装axios组件实例

    首先要创建一个网络模块network文件夹  里面要写封装好的几个组件 在config.js里面这样写 在index.js要这样写 core.js文件里面内容如下 然后要在main.js文件里面要设置 ...

  2. 基于Vue的简单日历组件

    日历组件 由于移动端项目中需要用到日历组件,网上找了下,没看到几个合适的,就尝试着自己写一个.然后发现也不是很复杂,目前只做了最基本的功能,大家也可以拿去做做二次开发. 如何写一个日历组件 基础效果如 ...

  3. Vue自行封装常用组件-弹出框

    使用方法: 1.在父组件中引入"box.vue" //import popUpBox from "./box.vue";   2.在父组件中注册 popUpBo ...

  4. vuetify | vue | 文件上传组件 | file | upload | form input[type="file"]

    今天无聊地写vuecli3听歌的时候,遇到了上传文件到Django的自我需求,然后就到vuetify的表单组件里找upload btn,发现居然没有!!! 顿时惊了个呆,要知道之前用element做操 ...

  5. Vue 数组封装和组件data定义为函数一些猜测

     数组封装 var vm={ list:[0,1] } var push=vm.list.push;//把数组原来的方法存起来 vm.list.push=function(arg){//重新定义数组的 ...

  6. Vue自行封装常用组件-倒计时

    倒计时组件,比较复杂一点,大神勿调侃,精确到毫秒,因为项目中多次出现倒计时,所以拿出来分享下 使用方法:1.在父组件中引入"uni-countdown" //import uniC ...

  7. [ vue ] Quasar封装q-dialog组件,在外层实现弹出框的开启和关闭

    场景描述: 见:https://www.cnblogs.com/remly/p/12981582.html 具体实现: <!-- 父组件 --> <template> < ...

  8. Vue自行封装常用组件-文本提示

    使用方法:1.在父组件中引入"toast.vue" //import toast from "./toast"; 2.在父组件中注册 toast //compo ...

  9. vue中封装swipe组件

    <template> <!-- TODO swipe --> <div id="hy-swiper"> <div class=" ...

随机推荐

  1. 【原创】Vue.js 中 axios 跨域访问错误

    1.假如访问的接口地址为 http://www.test.com/apis/index.php  (php api 接口) 2.而开发地址为http://127.0.0.1:8080,当axios发起 ...

  2. [tyvj 1061] Mobile Service (线性dp 滚动数组)

    3月15日第一题! 题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Local 题目描述 一个公司有三个移动服务员.如果某个地方有一个请求,某个员工必须 ...

  3. 【ACM-ICPC 2018 南京赛区网络预赛 E】AC Challenge

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 写个DP 设f[j]表示已经做的题的状态为j的情况下接着选能获得的最大分数. 显然是个倒推. 记忆化搜索一波 dfs(i,j) 表示 ...

  4. C#基础--索引器

    classProgram { staticvoidMain(string[] args) { man mm =new man(); mm[0]="jingya"; mm[1]=&q ...

  5. CAD教程----圆的优化命令viewres

    CAD软件为了节省内存加快打开图纸的速度,会在显示圆形的时候,用很粗燥的直线表示园,这时我们可以不节省内存,使用viewres将圆形完整的显示出来. 这个值设置的越大,圆越圆(好绕口!)

  6. 由free命令想到的

    root@xdj-Z9PA-D8-Series:~# free -m total used free shared buffers cached Mem: 15977 1683 14293 0 132 ...

  7. ShareREC for iOS v1.0.4 已经公布

    ShareREC for iOS v1.0.4 已经公布 版本号:v1.0.4 2015-3-13 1.新增视频列表的筛选排序功能 2.修复在開始录制后,没有调用结束录制直接进入社区崩溃问题 3.优化 ...

  8. 2015.05.12,外语,读书笔记-《Word Power Made Easy》 15 “如何谈论不同人的特点” SESSION 45

    TEASER PREVIEW 以-ous结尾的,描绘某人特点的词语包括: fawning(['fɔ:niŋ] adj.奉承的),servilely(['sә:vail] adj. 卑屈的, 奴隶的) ...

  9. win32 Service memory leak

    https://stackoverflow.com/questions/2728578/how-to-get-phyiscal-path-of-windows-service-using-net ht ...

  10. oracle得到建表语句

    第一种方法是使用工具,如:pl/sql developer,在[工具]--[导出用户对象]出现就可以得到建表脚本. 第二种方法是,sql语句. DBMS_METADATA.GET_DDL包可以得到数据 ...