整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          手把手教你用vue 編寫一個日歷組件「實踐」

          手把手教你用vue 編寫一個日歷組件「實踐」

          信有不少小伙伴和我一樣一提到日歷就腦殼疼,然后去網(wǎng)上搜索好用的日歷組件,如element-ui什么的,但是日歷畢竟是別人開發(fā)出來的, 和自己家ui設計出來的功能樣式畢竟不能100%相似,所以這個時候要么就去git上找一個相似的然后去修改代碼,要么就只能自己開發(fā)一個了,所以我也是把我自己學到的日歷組件封裝思路分享給大家;

          雖然我知道日歷組件肯定已經(jīng)有很多人發(fā)過文章,寫過思路了,但是我還是想寫一下。

          準備工作

          我是選擇弄一個新的腳手架去開發(fā),所以我是去vue-cli官網(wǎng)去拉取一個新的腳手架在本地,相信這個大家應該都會。 拉取成功之后npm serve 啟動;

          image.png

          然后我習慣一點用less寫css樣式,所以我在裝一個less和less-loader,然后這個因人而異;

          開始

          image.png

          相信很多小伙伴和我一樣看到日歷之后不知道怎么下手,如何能區(qū)分上下月和當前月呢,其實明白思路和原理之后就很簡單。

          一個日歷有的是42天有的是35天,原因是6行或7行,7行展示的就比較全面;42天的優(yōu)點是能全部展示出上個月,當前月以及下個月,缺點是上個月和下個月占比較多,有些冗余,如果是35天看起來就會比較精簡,但有的月份就不能全部展示出來還是需要42天,這個也無傷大雅,我們就以42天為例;

          首先我們需要看當前月的第一天是周幾,5月的1號就是周三,那么就用42 - 2(這里注意如果是周日在第一個就是42 - 周幾,如果是周一在第一個就是42 - (周幾 - 1 )剩下的就是當前月和下個月的日期了。

          我創(chuàng)建一個公共js里面放一些公共的方法方便在組件中調(diào)用;公共的js我就叫utils.js;
          getYearMonthDay 就是utils里面的一個公共方法,是為了方便獲取年月日;
          const getYearMonthDay=(date)=> {
           let year=date.getFullYear();
           let month=date.getMonth();
           let day=date.getDate();
           return {year, month, day};
          };
          
          computed: {
              visibleCalendar: function () {
                  let calendatArr=[];
                  先得到當前的年,月,日
                  let {year, month, day}=utils.getNewDate(utils.getDate(this.time.year, this.time.month, 1));
                  
                  獲取當月的第一天 得到2019-5-1
                  let currentFirstDay=utils.getDate(year, month, 1);
                  
                  獲取第一天是星期幾 得到 3
                  let weekDay=currentFirstDay.getDay();
                  
                  用當月的第一天減去 周幾前面幾天 這樣就能得到上個月開始的天數(shù) (當前月1號是周三,那么周一就是上個月的最后兩天)
                  let startTime=currentFirstDay - (weekDay - 1) * 24 * 60 * 60 * 1000;
                  
                  然后得到所有的日期
                  for (let i=0; i < 42; i++) {
                    calendatArr.push({
                      date: new Date(startTime + i * 24 * 60 * 60 * 1000),
                      year: year,
                      month: month + 1,
                      day: new Date(startTime + i * 24 * 60 * 60 * 1000).getDate()
                    })
                  };
                  return calendatArr
              }
          }
          
          

          然后dom結構去v-for這個數(shù)組,這樣就能得到一個初始的日歷了

          image.png


          但是這樣很丑,而且不能區(qū)分出哪一天是上個月哪一天是下個月,所以我們需要給上下月去加一下樣式來區(qū)分當前月和上下月的區(qū)分

          <ul class="calendar-view clear">
            <li v-for="(item, index) in visibleCalendar" 
              :key="index" 
              class="date-view"
              :class="[
                {'notCurrentMonth-class': !isCurrentMonth(item.date)},
                {currentDay: isCurrentDay(item.date)},
              ]"
              @click="handleClickDay(item, index)"
            >
              <span class="date-day" >
                {{item.day}}
              </span>
            </li>
          </ul>
          notCurrentMonth-class 是區(qū)分上下月的類名
          currentDay 是判斷是否是今天的類名
          
          判斷是否是當前月的方法,傳入每一天 用傳入的每一天去和當前年月做比較然后返回
          isCurrentMonth (date) {
              let {year: currentYear, month: currentMonth}=utils.getYearMonthDay(utils.getDate(this.time.year, this.time.month, 1));
              let {year, month}=utils.getYearMonthDay(date);
              return currentYear==year && currentMonth==month
          }
          判斷是否是當前天的方法 同理
          isCurrentDay (date) {
              let {year: currentYear, month: currentMonth, day: currentDay}=utils.getYearMonthDay(new Date());
              let {year, month, day}=utils.getYearMonthDay(date);
              return currentYear==year && currentMonth==month && currentDay==day;
          }
          
          

          然后給類名加一些自己喜歡的樣式就可以愉快的區(qū)分出當前月和上下月以及今天

          image.png

          現(xiàn)在就差左右切換和點擊今天回到當前月了,接下來就很簡單,我們先寫兩個方法用來切換上下月

          先去utils里面創(chuàng)建一個新的方法用來獲取當前幾月幾日
          const getDate=(year, month, day)=> {
            return new Date(year, month, day);
          }
          在data () {
              let {year, month, day}=utils.getYearMonthDay(new Date());
              return {
                  yearMonth: {year, month, day}, 
              }
          }
          // 上一個月 獲取當年月 用setMonth()去設置月份,然后更新yearMonth
            handlePrevMonth () {
              let prevMonth=utils.getDate(this.yearMonth.year,this.yearMonth.month,1);
              prevMonth.setMonth(prevMonth.getMonth() - 1);
              this.yearMonth=utils.getYearMonthDay(prevMonth);
            }
            // 下一個月 獲取當年月 用setMonth()去設置月份,然后更新yearMonth
            handleNextMonth () {
              let nextMonth=utils.getDate(this.yearMonth.year,this.yearMonth.month,1); 
              nextMonth.setMonth(nextMonth.getMonth() + 1);
              this.yearMonth=utils.getYearMonthDay(nextMonth);
            }
            // 點擊回到今天 同理
            handleToday () {
              this.yearMonth=utils.getYearMonthDay(new Date());
            }
          

          就這樣一個左右切換以及點擊回到今天的日歷就完成了,是不是非常非常的簡單?

          gitHub 日歷地址:https://github.com/xiangnideye/vue-date-picker

          我把詳細的代碼上傳到了我的gitHub上面,在git上面我寫的更詳細一些,也提供了一些對外的點擊事件,這樣在組件的外面可以調(diào)用里面的一些方法,這樣用起來更方便,如果你覺得還不錯,可以去git上面給個星星或者是啥的,感謝大家支持,如果有說的不對的地方,歡迎指出,共同探討!


          作者:Alawaysonl_c839
          鏈接:https://www.jianshu.com/p/d8ce25e9badb

          datefns為瀏覽器中操作JavaScript日期提供了最全面、最簡單、最一致的工具集,并且可以在node.js中使用!常見的類似的庫還有moment.js和day.js!





          Github

          https://github.com/date-fns/date-fns

          特性

          • 模塊化

          只是用需要使用的功能,可以很好地與webpack, Browserify, 或者 Rollup集成

          • 原生日期

          date-fns不會重新造輪子,而是使用現(xiàn)有的本機類型。此外,出于安全考慮,它不會擴展核心對象。date-fns中的函數(shù)可以正常工作,在某些情況下會遵循ECMAScript行為。

          • 純函數(shù)

          date-fns是使用純函數(shù)構建的,并且始終返回新的日期實例,而不是更改傳遞的實例。這有助于防止錯誤并避免長時間的調(diào)試會話。

          • 支持Typescript和Flow

          date-fns支持FlowTypeScript

          • 國際化

          支持幾十種語言,當然包括了簡體中文,只有當你需要使用的時候才會包括進來

          • 一致性

          它總是返回同一時區(qū)中的日期,不管傳遞的是時間戳、字符串還是日期對象。該API經(jīng)過定制,具有可預測的名稱和參數(shù)順序。

          • 可靠性

          datefns尊重時區(qū)和夏時制。它遵循語義版本控制,因此始終向后兼容。每個構建CI在大約400個時區(qū)檢查超過650000個示例

          • 簡單

          最好的API是不存在API。對于date fns,你總是有一個函數(shù)可以做一件事。并且總是有一個單一的方法來解決問題。

          • 性能好

          除了體積小之外,date-fns速度很快。

          • 詳細的文檔

          每個函數(shù)都有一個詳細的例子說明。由于JSDoc注釋,文檔可以在線(在網(wǎng)站上)和離線訪問。




          示例

          • 格式化
          import { format, formatDistance, formatRelative, subDays } from 'date-fns'
          
          format(new Date(), "'Today is a' iiii")
          //=> "Today is a Thursday"
          
          formatDistance(subDays(new Date(), 3), new Date())
          //=> "3 days ago"
          
          formatRelative(subDays(new Date(), 3), new Date())
          //=> "last Friday at 7:26 p.m."
          • 國際化
          import { formatRelative, subDays } from 'date-fns'
          import { es, ru } from 'date-fns/locale'
          
          formatRelative(subDays(new Date(), 3), new Date())
          //=> "last Friday at 7:26 p.m."
          
          formatRelative(subDays(new Date(), 3), new Date(), { locale: es })
          //=> "el viernes pasado a las 19:26"
          
          formatRelative(subDays(new Date(), 3), new Date(), { locale: ru })
          //=> "в прошлую пятницу в 19:26"
          • 日常使用
          import { addYears, formatWithOptions, toUpper } from 'date-fns/fp'
          import { eo } from 'date-fns/locale'
          
          const addFiveYears=addYears(5)
          
          const dateToString=formatWithOptions({ locale: eo }, 'D MMMM YYYY')
          
          const dates=[
            new Date(2017, 0, 1),
            new Date(2017, 1, 11),
            new Date(2017, 6, 2)
          ]
          
          const toUpper=arg=> String(arg).toUpperCase()
          
          const formattedDates=dates.map(addFiveYears).map(dateToString).map(toUpper)
          //=> ['1 JANUARO 2022', '11 FEBRUARO 2022', '2 JULIO 2022']

          總結

          不論是moment.js或者day.js亦或是datefns都是JavaScript中處理日期非常好的庫,也避免了很多日期處理中的很多問題!

          今每個人的事情都變的越來越多了,沒有一個好的提醒工具,你會不會錯過很多,比如:交房貸、追劇、看球等等,我們知道手機上的日歷,時鐘,都能提醒我們,可是作為程序員的我們,是不是也該嘗試一下,弄一個日歷處理?

          首先明確,我們需要什么功能:通過日歷來展示我們的待辦事項?

          如果從頭寫,是不是有點費時?這里,我們推薦一個jQuery插件:FullCalendar

          我們先目的一下它的風采吧。

          首先,F(xiàn)ullCalendar最大的特點是,可以全日歷上拖放的,比如:我5月19號添加的備忘,可以拖放到5月31號上。添加的備忘事件還可以跨好幾天來拖放,真的很方便。

          那么FullCalendar是什么?

          嚴格的說,它是一個開源的,并可定制的JavaScript事件日歷,支持全尺寸拖放。

          這里有個比較重要的聲明:它是一個很好的活動展示庫,不是一個完整的事件管理解決方案,就是說不能修改活動事件的名稱。你需要通過它的JS函數(shù)和配置等來設置。

          那么如何獲取它?

          你可以通過github來搜索FullCalendar,它也有官網(wǎng)可以查看各種示例(當然也包括Google日歷的Style)

          那么它的兼容性如何?

          它支持Firefox、Chrome、Safari、IE9+等所有現(xiàn)代瀏覽器。它依賴于jQuery 2.0.0+、Moment 2.9.0+(這是一個對日歷和時間進行解析、驗證、操作、顯示的js庫)

          那么如何使用它呢?

          通過上圖的Head部分引用,Script,Html,就可以完成一個日歷的展示了。

          至此,這個開源的日歷庫就介紹完了,如果工作中有需要,它是個不錯的選擇。看文章累了嗎?來張圖片養(yǎng)養(yǎng)眼?(圖片來源網(wǎng)絡,如有侵權請告知。)

          圖片來自網(wǎng)絡,如有侵權請告知,我們會盡快刪除。謝謝。


          主站蜘蛛池模板: 国语对白一区二区三区| 精品一区二区视频在线观看| 在线免费一区二区| 精品3d动漫视频一区在线观看| 国产精品无码一区二区在线观| 高清一区二区三区| 国产小仙女视频一区二区三区| 国产高清一区二区三区四区| 国产乱码精品一区二区三区中| 亚洲一区二区精品视频| 亚洲一区二区三区丝袜| 国产精品美女一区二区视频 | 精品中文字幕一区二区三区四区| 国产成人一区二区三区在线| 日韩精品电影一区| 内射女校花一区二区三区| 中文字幕乱码亚洲精品一区| 激情一区二区三区| 一区二区三区免费电影| 视频一区视频二区制服丝袜 | 无码播放一区二区三区| 国产一区二区在线观看app| 色视频综合无码一区二区三区| 国产在线观看一区二区三区| 91无码人妻精品一区二区三区L| 日本成人一区二区| 日韩好片一区二区在线看| 无码少妇精品一区二区免费动态| 久久精品一区二区| 日本不卡在线一区二区三区视频| 插我一区二区在线观看| 国产精品无码一区二区三级| 性色av一区二区三区夜夜嗨 | 国产美女av在线一区| 国产日韩AV免费无码一区二区三区| 乱人伦一区二区三区| 亚洲bt加勒比一区二区| 最新中文字幕一区二区乱码| 亚洲熟女乱色一区二区三区 | 一区五十路在线中出| 亚洲AV无码一区东京热|