vue實現(xiàn)日歷組件

1、當(dāng)前組件說明

一個用vue實現(xiàn)的簡單日歷組件罢吃,可以手動設(shè)置日歷的寬高楚午,未設(shè)置時,有默認(rèn)寬高尿招,設(shè)置后矾柜,其中的每個日期項的寬高可以根據(jù)設(shè)定的寬高自適應(yīng)、可以設(shè)置當(dāng)前選中日期就谜,可以設(shè)置時間可用范圍怪蔑,可以通過左右箭頭進行日期切換。(第一次使用簡書丧荐,代碼格式比較丑缆瓣,而且換行很高,也不知道怎么調(diào)整虹统,大家見諒)

2弓坞、組件效果展示

3、組件實現(xiàn)代碼

<template>

??<div?class="picker-box"?:style="'width:?'?+?width?+?'px;?height:?'?+?height?+?'px;'">

????<div?class="picker-tool"?:style="'height:?'?+?toolHeight?+?'px;?line-height:?'?+?toolHeight?+?'px;'">

??????<Button?type="text"?icon="ios-arrow-back"?@click="toVdpUpper()"></Button>

??????{{vdpYear?+?'年'?+?vdpMonth?+?'月'}}

??????<Button?type="text"?icon="ios-arrow-forward"?@click="toVdpLower()"></Button>

????</div>

????<div?class="picker-body"?:style="'height:?'?+?(height?-?50)?+?'px;'">

??????<div?class="picker-title"?v-for="item?in?xqList"?:key="item"?:style="itemStyles">{{item}}</div>

??????<div?class="picker-item"

????????:style="itemStyles"

????????v-for="(item,?i)?in?dateList"?:key="i"?@click="toSelect(item)"

????????:class="(item.disabled?===?false?&&?item.actived???'actived'?:'grey')?+?(item.checked???'?checked'?:?'')?+?(item.today???'?today'?:?'')?+?(item.disabled???'?disabled'?:?'')">

??????????{{item.day}}

???????</div>

??????<div?style="clear:?both;"></div>

????</div>

??</div>

</template>

<script>

export?default?{

??name:?'cDatePicker',

??props:?{

????//?要求傳入的值?必須為?yyyy-MM-dd?格式數(shù)據(jù)

????value:?{

??????type:?String

????},

? ? // 日歷顯示的寬度车荔,默認(rèn)300px

????width:?{

??????type:?Number,

??????default:?300

????},

? ???// 日歷顯示的高度渡冻,默認(rèn)300px

????height:?{

??????type:?Number,

??????default:?300

????},

? ???// 日歷工具欄的顯示高度,默認(rèn)32px

?????toolHeight:?{

??????type:?Number,

??????default:?32

????},

? ??// 日歷中每個時間項的行高

????lineHeight:?{

??????type:?Number

????},

????margin:?{

??????type:?Number,

??????default:?2

????},

????// 日歷可選范圍-開始時間

????start:?{

??????type:?String,

??????default:?''

????},

????// 日歷可選范圍-結(jié)束時間

????end:?{

??????type:?String,

??????default:?''

????}

??},

??watch:?{

????//?監(jiān)聽?外部插入的value值變化

????//?value?(n,?l)?{

????//???this.init()

????//?}

??},

??data?()?{

????return?{

??????xqList:?['日',?'一',?'二',?'三',?'四',?'五',?'六'],

??????vdpYear:?0,?//?選擇的年

??????vdpMonth:?0,?//?選擇的月

??????vdpDay:?0,?//?選擇的日

??????monthStart:?0,?//?月初

??????monthEnd:?0,?//?月末

??????monthWeek:?0,

??????dateList:?[]?//?當(dāng)前時間集合

????}

??},

??methods:?{

????//?初始化

????init?()?{

??????const?now?=?this.newDate(this.value?||?undefined)

??????this.vdpYear?=?now.getFullYear()

??????this.vdpMonth?=?now.getMonth()?+?1

??????this.vdpDay?=?this.value???now.getDate()?:?0

??????this.computePicker()

????},

????//?選中某一天

????toSelect?(item)?{

??????if?(item?&&?item.disabled?===?false)?{

????????//?//?通過重新生成dateList數(shù)據(jù)?達到改變選中效果

????????//?this.vdpDay?=?item.day

????????//?this.computePicker()

????????//?通過?直接循環(huán)修改dateList數(shù)據(jù)?達到改變選中效果

????????this.dateList?=?this.dateList.map(v?=>?{

??????????v.checked?=?false

??????????return?v

????????})

????????this.vdpDay?=?item.day

????????item.checked?=?true

????????this.$emit('input',?item.date)

????????this.$emit('on-change',?item.date,?this.newDate(item.date))

??????}

????},

????//?上一個月

????toVdpUpper?()?{

??????if?(this.vdpMonth?>?1)?{

????????this.vdpMonth--

??????}?else?{

????????this.vdpYear--

????????this.vdpMonth?=?12

??????}

??????this.vdpDay?=?0

??????this.computePicker()

????},

????//?下一個月

????toVdpLower?()?{

??????if?(this.vdpMonth?<?12)?{

????????this.vdpMonth++

??????}?else?{

????????this.vdpYear++

????????this.vdpMonth?=?1

??????}

??????this.vdpDay?=?0

??????this.computePicker()

????},

????//?計算月初忧便、月末族吻、月初是星期幾及當(dāng)前日期數(shù)據(jù)

????computePicker?()?{

??????const?yc?=?new?Date(this.vdpYear,?this.vdpMonth?-?1,?1)?//?月初

??????const?ym?=?new?Date(this.vdpYear,?this.vdpMonth,?0)?//?月末

??????this.monthStart?=?yc.getDate()

??????this.monthEnd?=?ym.getDate()

??????this.monthWeek?=?yc.getDay()

??????const?v?=?[]

??????for?(let?i?=?0;?i?<?42;?i++)?{

????????v.push(this.getVdpDay(i,?'-'))

??????}

??????this.dateList?=?v

????},

????//?獲取當(dāng)前日期?核心方法

????getVdpDay?(index,?defV)?{

??????let?_disabled?=?false

??????let?_actived?=?false

??????let?_year?=?this.vdpYear

??????let?_month?=?this.vdpMonth

??????let?_day?=?0

??????if?(this.monthWeek?===?0)?{

????????index?=?index?-?7

??????}

??????if?(index?<?this.monthWeek)?{

????????//?計算上月

????????_month--

????????if?(_month?===?0)?{

??????????_year--

??????????_month?=?12

????????}

????????_day?=?new?Date(_year,?_month,?0).getDate()?-?this.monthWeek?+?index?+?1?//?算當(dāng)前選中月的上一月?月末

??????}?else?if?(index?>?(this.monthWeek?+?this.monthEnd?-?1))?{

????????//?計算下月

????????_month++

????????if?(_month?===?13)?{

??????????_year++

??????????_month?=?1

????????}

????????_day?=?new?Date(this.vdpYear,?this.vdpMonth,?1).getDate()?+?index?-?(this.monthEnd?+?this.monthWeek)?//?算當(dāng)前選中月的下一月?月初

??????}?else?{

????????//?計算當(dāng)月

????????_day?=?this.monthStart?+?index?-?this.monthWeek

????????_actived?=?true

??????}

??????//?計算開始日期和結(jié)束日期

??????if?(this.start?||?this.end)?{

????????const?_curtm?=?new?Date(_year?+?'/'?+?_month?+?'/'?+?_day)

????????if?(this.start)?{

??????????const?_start?=?this.newDate(this.start)

??????????if?(_curtm?<?_start)?{

????????????_disabled?=?true

??????????}

????????}

????????if?(this.end)?{

??????????const?_end?=?this.newDate(this.end)

??????????if?(_curtm?>?_end)?{

????????????_disabled?=?true

??????????}

????????}

??????}

??????return?{?year:?_year,?month:?_month,?day:?_day,?date:?this.generateDateStr(_year,?_month,?_day),?checked:?this.verifyCheckDate(_year,?_month,?_day),?actived:?_actived,?today:?this.isToday(_year,?_month,?_day),?disabled:?_disabled?}?//?_disabled???(defV?||?'')?:?_day

????},

????//?生成時間字符串

????generateDateStr?(year,?month,?day)?{

??????return?year?+?'-'?+?(month?>?9???month?:?'0'?+?month)?+?'-'?+?(day?>?9???day?:?'0'?+?day)

????},

????//?驗證是否是當(dāng)前選中的日期

????verifyCheckDate?(year,?month,?day)?{

??????if?((this.value?&&?this.value?===?this.generateDateStr(year,?month,?day))?||?(this.vdpYear?===?year?&&?this.vdpMonth?===?month?&&?this.vdpDay?===?day))?{

????????return?true

??????}?else?{

????????return?false

??????}

????},

????//?驗證是否今天

????isToday?(year,?month,?day)?{

??????if?(this.generateDateStr(year,?month,?day)?===?this.formatDate(new?Date(),?'yyyy-MM-dd'))?{

????????return?true

??????}?else?{

????????return?false

??????}

????},

????//?字符串轉(zhuǎn)換?Date?解決ie11?時間兼容性問題

????newDate?(time,?defV)?{

??????let?v?=?defV?===?undefined???new?Date()?:?defV

??????if?(time)?{

????????v?=?new?Date(time.replace(/-/g,?'/'))

??????}

??????return?v

????},

????//?時間格式化?兼容IE

????formatDate?(date,?format)?{

??????if?(date)?{

????????var?time

????????if?(typeof?date?===?'string')?{

??????????time?=?new?Date(date.replace(/-/g,?'/'))

????????}?else?if?(typeof?date?===?'object')?{

??????????time?=?new?Date(date)

????????}

????????var?o?=?{

??????????'M+':?time.getMonth()?+?1,?//?月份

??????????'d+':?time.getDate(),?//?日

??????????'h+':?time.getHours(),?//?小時

??????????'m+':?time.getMinutes(),?//?分

??????????'s+':?time.getSeconds(),?//?秒

??????????'q+':?Math.floor((time.getMonth()?+?3)?/?3),?//?季度

??????????S:?time.getMilliseconds()?//?毫秒

????????}

????????if?(/(y+)/.test(format))?format?=?format.replace(RegExp.$1,?(time.getFullYear()?+?'').substr(4?-?RegExp.$1.length))

????????for?(var?k?in?o)?{?if?(new?RegExp('('?+?k?+?')').test(format))?format?=?format.replace(RegExp.$1,?(RegExp.$1.length?===?1)???(o[k])?:?(('00'?+?o[k]).substr((''?+?o[k]).length)))?}

????????return?format

??????}?else?{?return?''?}

????}

??},

??computed:?{

????itemStyles?()?{

??????const?_w?=?(this.width?/?7?-?this.margin?*?2)

??????const?_h?=?((this.height?-?this.toolHeight)?/?7?-?this.margin?*?2)

??????const?_lh?=?this.lineHeight???this.lineHeight?:?(_h?-?1)?+?'px'?//?parseInt(_h)

??????return?{?width:?_w?+?'px',?height:?_h?+?'px',?margin:?this.margin?+?'px',?'line-height':?_lh?}

????}

??},

??created?()?{

????this.init()

??}

}

</script>

<style?scoped>

.picker-box?{

??width:?100%;

??height:?100%;

??margin:?0?auto;

??font-size:?14px;

}

.picker-box?.picker-tool?{

??height:?50px;

??line-height:?50px;

??text-align:?center;

}

.picker-box?.picker-body?{

??width:?100%;

}

.picker-box?.picker-body?.picker-item,?.picker-box?.picker-body?.picker-title??{

??width:?calc(14.285714285%?-?10px);

??height:?calc(16.666666666%?-?10px);

??line-height:?2.6;

??text-align:?center;

??border:?1px?solid?#ececec;

??border-radius:?5px;

??margin:?5px;

??float:?left;

}

.picker-box?.picker-body?.picker-item?{

??cursor:?pointer;

}

.picker-box?.picker-body?.picker-title?{

??background:?#eaf0f5;

}

.picker-box?.picker-body?.grey?{

??color:?#b2b2b2;

??border:?1px?solid?#ececec;

??background:?#fbfbfb;

}

.picker-box?.picker-body?.actived?{

??color:?#3c3c3c;

??border:?1px?solid?#ececec;

}

.picker-box?.picker-body?.today?{

??background:?#d8f9d8;

??border:?1px?solid?#ececec;

}

.picker-box?.picker-body?.checked?{

??color:?#fff;

??background:?#19be6b;

??border:?1px?solid?#19be6b;

}

.picker-box?.picker-body?.disabled?{

??color:?#b2b2b2;

??background:?#f2f2f2;

??border:?1px?solid?#ececec;

??cursor:?not-allowed;

}

</style>

4、組件調(diào)用示例

<template>

??<div>

??????<cDatePicker?v-model="timeText"></cDatePicker>

??????<cDatePicker?v-model="timeText"?:start="start"?:end="end"?:width="500"?:height="500"?:tool-height="50"?:margin="5"></cDatePicker>

??</div>

</template>

<script>

import?cDatePicker?from?'./cDatePicker'

export?default?{

??components:?{

????cDatePicker

??},

??data?()?{

????return?{

??????timeText:?'2020-07-16',

??????start:?'2020-06-12',

??????end:?'2020-08-05'

????}

??}

}

</script>

5珠增、尚需待完善

a超歌、點擊年,進行年份切換

b蒂教、點擊月握础,進行月份切換。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末悴品,一起剝皮案震驚了整個濱河市禀综,隨后出現(xiàn)的幾起案子简烘,更是在濱河造成了極大的恐慌,老刑警劉巖定枷,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孤澎,死亡現(xiàn)場離奇詭異,居然都是意外死亡欠窒,警方通過查閱死者的電腦和手機覆旭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岖妄,“玉大人型将,你說我怎么就攤上這事〖雠埃” “怎么了七兜?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長福扬。 經(jīng)常有香客問我腕铸,道長,這世上最難降的妖魔是什么铛碑? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任狠裹,我火速辦了婚禮,結(jié)果婚禮上汽烦,老公的妹妹穿的比我還像新娘涛菠。我一直安慰自己,他們只是感情好撇吞,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布碗暗。 她就那樣靜靜地躺著,像睡著了一般梢夯。 火紅的嫁衣襯著肌膚如雪言疗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天颂砸,我揣著相機與錄音噪奄,去河邊找鬼。 笑死人乓,一個胖子當(dāng)著我的面吹牛勤篮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播色罚,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼碰缔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了戳护?” 一聲冷哼從身側(cè)響起金抡,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤瀑焦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后梗肝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體榛瓮,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年巫击,在試婚紗的時候發(fā)現(xiàn)自己被綠了禀晓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡坝锰,死狀恐怖粹懒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情顷级,我是刑警寧澤凫乖,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站愕把,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏森爽。R本人自食惡果不足惜恨豁,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望爬迟。 院中可真熱鬧橘蜜,春花似錦、人聲如沸付呕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽徽职。三九已至象颖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間姆钉,已是汗流浹背说订。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留潮瓶,地道東北人陶冷。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像毯辅,于是被迫代替她去往敵國和親埂伦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354