国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

Vue 組件(component)教程之實(shí)現(xiàn)精美的日歷方法示例

2019-11-19 14:34:02
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

組件(component)是Vue最強(qiáng)大的功能之一。組件可以擴(kuò)展HTML元素,封裝可重用的代碼,根據(jù)項(xiàng)目需求,抽象出一些組件,每個(gè)組件里包含了展現(xiàn)、功能和樣式。每個(gè)頁(yè)面,根據(jù)自己的需要,使用不同的組件來(lái)拼接頁(yè)面。這種開(kāi)發(fā)模式使得前端頁(yè)面易于擴(kuò)展,且靈活性高,而且組件之間也實(shí)現(xiàn)了解耦。

最近應(yīng)公司的要求,需要開(kāi)發(fā)一個(gè)精美的日歷組件(IOS , 安卓, PC 的IE9+都能運(yùn)行),寫完后想把它分享出來(lái),希望大家批評(píng)。

先來(lái)個(gè)截圖

  

 代碼已經(jīng)分享到 https://github.com/zhangKunUserGit/vue-component  (本地下載

使用方法

根據(jù)需求先說(shuō)一下怎么用吧 (上面是:HTML, 下面是JS )

<date-picker v-if="showDatePicker" :date="date" :min-date="minDate" :max-date="maxDate" @confirm="confirm" @cancel="cancel" ></date-picker>
import DataPicker from './components/DatePicker.vue';import './style.scss';new Vue({ el: '#app', data() { return { date: '2017-09-11', minDate: '2000-09-11', maxDate: '2020-09-11', showDatePicker: false, selectedDate: '點(diǎn)擊選擇日期', }; }, methods: { openDatePicker() { this.showDatePicker = true; }, confirm(value) { this.showDatePicker = false; this.selectedDate = value; }, cancel() { this.showDatePicker = false; }, }, components: { DataPicker, },});

我們提供了最大值、最小值和初始值,唯一不足的地方是時(shí)間格式只能是YYYY-MM-DD (2017-12-12) ,大家可以從github上拉取代碼運(yùn)行看一下(由于沒(méi)有仔細(xì)測(cè)試,可能會(huì)有bug和性能問(wèn)題,希望指出)。

(一)先畫好界面

這個(gè)不是重點(diǎn),HTML 和 CSS,應(yīng)該很簡(jiǎn)單,大家看我的css 可能感覺(jué)我的命名太長(zhǎng)了,只因?yàn)槲覀児居茫瑩?dān)心其他樣式影響它(可能有其他方式吧,希望大神指出)

(二)組裝日期列表

先看代碼:

rows() { const { year, month } = this.showDate; const months = (new Date(year, month, 0)).getDate(); const result = []; let row = []; let weekValue; // 按照星期分組 for (let i = 1; i <= months; i += 1) { // 根據(jù)日期獲取星期,并讓開(kāi)頭是1,而非0 weekValue = (new Date(year, month, i)).getDay() + 1; // 判斷月第一天在星期幾,并填充前面的空白區(qū)域 if (i === 1 && weekValue !== 1) { this.addRowEmptyValue(row, weekValue); this.addRowDayValue(row, i); } else { this.addRowDayValue(row, i); // 判斷月最后一天在星期幾,并填充后面的空白區(qū)域 if (i === months && weekValue !== 7) { this.addRowEmptyValue(row, (7 - weekValue) + 1); } } // 按照一周分組 if (weekValue % 7 === 0 || i === months) { result.push(row); row = []; } } this.showDate.monthStr = monthJson[this.showDate.month]; return result;},

我的思路是:

  (1)獲取月份天數(shù),并按照星期分組;

  (2)如果月份第一天不在星期一,前面填充空值。同理,如何月份最后一天不在周日,最后面填充空值,目的是:讓分的組 長(zhǎng)度都是7,也就是一周。這樣可以用flex布局方式快速開(kāi)發(fā)了;

  (3)里面也包含一些限制,比如小于minDate和大于maxDate, 不讓點(diǎn)擊等等

(三)切換月份

(1)上一個(gè)月份

/** * 切換到上一個(gè)月 */prevMonth() { if (this.prevMonthClick) { return; } this.prevMonthClick = true; setTimeout(() => { this.prevMonthClick = false; }, 500); this.fadeXType = 'fadeX_Prev'; // 如何當(dāng)前月份已經(jīng)小于等于minMonth 就不讓其在執(zhí)行 if (this.isMinLimitMonth()) { return; } const { year, month } = this.showDate; // 判斷當(dāng)前月份,如果已經(jīng)等于1(1就是一月,而不是二月) if (month <= 1) { this.showDate.year = year - 1; this.showDate.month = 12; } else { this.showDate.month -= 1; }},

setTimeout()主要是讓其顯示動(dòng)畫后自動(dòng)消失。 fadeXType 是動(dòng)畫類型

(2)下一個(gè)月份

/** * 切換到下一個(gè)月 */nextMonth() { if (this.nextMonthClick) { return; } this.nextMonthClick = true; setTimeout(() => { this.nextMonthClick = false; }, 500); this.fadeXType = 'fadeX_Next'; // 如何當(dāng)前月份已經(jīng)大于等于maxMonth 就不讓其在執(zhí)行 if (this.isMaxLimitMonth()) { return; } const { year, month } = this.showDate; // 判斷當(dāng)前月份,如果已經(jīng)等于12(12就是十二月) if (month >= 12) { this.showDate.year = year + 1; this.showDate.month = 1; } else { this.showDate.month += 1; }},

這里面的setTimeout() 和prevMonth方法的原理一樣。

上面兩種切換月份的功能主要注意:

   a. 因?yàn)橛衜inDate和maxDate,所以首先考慮的是不能超出這個(gè)限制。

   b. 要考慮切換月份后年的變化,當(dāng)月份大于12后,年加1 ,月變成 1。

(四)選擇年份

(1)點(diǎn)擊最上面的年,顯示年份列表

openYearList() { if (this.showYear) { this.showYear = false; return; } const index = this.yearList.indexOf(this.selectDate.year); this.showYear = true; // 打開(kāi)年列表,讓其定位到選中的位置上 setTimeout(() => { this.$refs.yearList.scrollTop = (index - 3) * 40; });},

(2)選擇年份

selectYear(value) { this.showYear = false; this.showDate.year = value; let type; // 當(dāng)日期在最小值之外,月份換成最小值月份 或者 當(dāng)日期在最大值之外,月份換成最大值月份 if (this.isMinLimitMonth()) { type = 'copyMinDate'; } else if (this.isMaxLimitMonth()) { // 當(dāng)日期在最大值之外,月份換成最大值月份 type = 'copyMaxDate'; } if (type) { this.showDate.month = this[type].month; this.showDate.day = this[type].day; this.resetSelectDate(this.showDate.day); return; } let dayValue = this.selectDate.day; // 判斷日是最大值,防止另一個(gè)月沒(méi)有這個(gè)日期 if (this.selectDate.day > 28) { const months = (new Date(this.showDate.year, this.showDate.month, 0)).getDate(); // 當(dāng)前月份沒(méi)有這么多天,就把當(dāng)前月份最大值賦值給day dayValue = months < dayValue ? months : dayValue; } this.resetSelectDate(dayValue);},

在切換年份時(shí)注意一下方面:

    a. 考慮minDate和maxDate,  因?yàn)槿绻澳氵x擇的月份是1月,但是限制是9月,在大于minDate(比如2017) 年份沒(méi)有問(wèn)題,但是到了minDate 的具體年份(比如2010),那么月份最小值只能是九月,需要修改月份,maxDate同理。

 b. 如何之前你選擇的day是31,由于切換年份后,這個(gè)月只有30天,記得把day 換成這個(gè)月最大值,也就是30。 

(五)處理原始數(shù)據(jù)

其實(shí)這一條正常情況下,應(yīng)該放在第一步講,但是我是根據(jù)我的開(kāi)發(fā)習(xí)慣來(lái)寫步驟的。我一般都是先寫功能,數(shù)據(jù)是模擬的,等寫好了,再考慮原始數(shù)據(jù)格式和暴露具體的方法等等,因?yàn)檫@樣不會(huì)改來(lái)改去,影響開(kāi)發(fā)和心情。

initDatePicker() { this.showDate = { ...this.splitDate(this.date, true) }; this.copyMinDate = { ...this.splitDate(this.minDate) }; this.copyMaxDate = { ...this.splitDate(this.maxDate) }; this.selectDate = { ...this.showDate };},splitDate(date, addStr) { let result = {}; const splitValue = date.split('-'); try { if (!splitValue || splitValue.length < 3) { throw new Error('時(shí)間格式不正確'); } result = { year: Number(splitValue[0]), month: Number(splitValue[1]), day: Number(splitValue[2]), }; if (addStr) { result.week = (new Date(result.year, result.month, result.day)).getDay() + 1; result.monthStr = monthJson[result.month]; result.weekStr = weekJson[result.week]; } } catch (error) { console.error(error); } return result;},

這里目的是:

 a. 處理原始數(shù)據(jù),把原始數(shù)據(jù)查分,用json緩存下來(lái),這樣方便后面操作和顯示。這里面我只兼容YYYY-MM-DD的格式,其他的都不兼容,如果你想兼容其他格式,你可以修改其代碼,或者用moment.js 等其他庫(kù)幫你做這件事情。

 b. 拆分后的格式如下:

year: '',month: '',day: '',week: '',weekStr: '',monthStr: '',

總結(jié)

上面就是開(kāi)發(fā)這個(gè)組件的詳細(xì)講解,如有不妥,請(qǐng)指出批評(píng)。 仔細(xì)想想,其實(shí)這個(gè)不難,就是有點(diǎn)瑣碎。仔細(xì)就好

這里的所有動(dòng)畫都是用的Vue 的 transition,大家可以看看官網(wǎng),非常詳細(xì)。

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)武林網(wǎng)的支持。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 肥西县| 彰化县| 麻栗坡县| 衢州市| 沂南县| 甘德县| 股票| 荆门市| 腾冲县| 西充县| 甘谷县| 乌兰县| 安国市| 广昌县| 石首市| 衡东县| 青铜峡市| 喀喇| 海口市| 阳新县| 锦州市| 渭南市| 佛山市| 鄂伦春自治旗| 聂拉木县| 枣强县| 尉犁县| 富宁县| 巫溪县| 鄂托克前旗| 浪卡子县| 化德县| 漳州市| 卢氏县| 新乡县| 云和县| 得荣县| 嵊州市| 漯河市| 理塘县| 永城市|