亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

vue實現一個炫酷的日歷組件

2019-11-19 12:46:53
字體:
來源:轉載
供稿:網友

公司業務新開了一個商家管理微信H5移動端項目,日歷控件是商家管理員查看通過日程來篩選獲取某日用戶的訂單等數據。 如圖: 假設今天為2018-09-02


90天前:


90天后;

產品需求:

  • 展示當前日期(服務器時間)前后90天,一共181天的日期。
  • 日歷可以左右滑動切換月份。
  • 當月份的如果不在181天區間的,需要置灰并且不可點擊。
  • 點擊日歷綁定的節點的外部,關閉彈窗。

涉及內容:

  1. 獲取服務器時間,渲染日歷數據
  2. vue-touch監聽手勢滑動事件
  3. ios日期兼容處理
  4. clickOutSide自定義指令
  5. mock模擬數據

開發:

參考了 基于Vue開發一個日歷組件 - 掘金 日歷的年月日計算方式。 核心思想:假設當前月份是二月份,根據二月和三月的1號是星期幾,來對二月進行布局。(如果需要在二月顯示一月和三月的日期,還需要知道一月份有多少天)

在項目開發中,為了與后臺同事并行開發。項目采用來mock模擬數據來攔截接口。

日歷展盤

// calendar.vue<template> <div class="cp-calendar"> <v-touch @swipeleft="handleNextMonth" @swiperight="handlePreMonth" class="calendar">  <div class="calendar-main" > <span class="item-con header-item"  v-for="(item, index) in calendarHeader"  :key="index">{{item}}</span> <div :class="`item-con ${todayStyle(item.content) && 'item-con-today'} ${item.type === 'disabled' && 'disableStyle'}`"  :style="{opacity: isChangeMonth ? 0 : 1}"  @click.stop="handleDayClick(item)"  v-for="(item, index) in getMonthDays(selectedYear, selectedMonth)"  :key="item.type + item.content + `${index}`">  <span  :class="`main-content ${selectedDateStyle(item.content) && 'selectedColor'}`">  {{setContent(item.content)}}</span>  <span :class="`${selectedDateStyle(item.content) && 'item-con-point'}`" ></span> </div> </div>  </v-touch> </div></template>

初始化數據 針對服務器時間進行初始數據處理

// calendar.vue// 設置初始數據 initData () { this.today = this.currentDate || getDateStr(0) // 如果沒有服務器時間,拿本地時間 this.prevDate = getDateStr(-90, this.currentDate) this.nextDate = getDateStr(90, this.currentDate) // 是否有手動選中的日期 let selectedFullDate = this.storeSelectedFullDate if (!this.storeSelectedFullDate) {  selectedFullDate = this.currentDate || getDateStr(0) // 如果沒有服務器時間,拿本地時間 } this.selectedYear = Number(selectedFullDate.split('-')[0]) this.selectedMonth = Number(selectedFullDate.split('-')[1]) - 1 this.selectedDate = Number(selectedFullDate.split('-')[2]) this.selectedFullDate = `${this.selectedYear}-${this.selectedMonth + 1}-${this.selectedDate}` }, / 渲染日期 getMonthDays(year, month) { // 定義每個月的天數,如果是閏年第二月改為29天 let daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {  daysInMonth[1] = 29; } // 當月第一天為周幾 let targetDay = new Date(year, month, 1).getDay(); let calendarDateList = []; let preNum = targetDay; let nextNum = 0; if (targetDay > 0) {  // 當前月份1號前的自然周剩余日期,置空  for (let i = 0; i < preNum; i++) {  let obj = {  type: 'pre',  content: ''  };  calendarDateList.push(obj);  } } // 判斷當前年月份 let formatMonth = month + 1 >= 10 ? month + 1 : '0' + (month + 1) this.prevYearMonthBoolean = (`${year}-${formatMonth}` === this.prevYearMonth) this.nextYearMonthBoolean = (`${year}-${formatMonth}` === this.nextYearMonth) for (let i = 0; i < daysInMonth[month]; i++) {  // 正常顯示的日期  let obj = {  type: 'normal',  content: i + 1  };  // 判斷是否為最往前或者最往后的月份,篩選出不可點擊的日期  if (this.prevYearMonthBoolean) {  let prevDay = this.prevDate.split('-')[2]  if (i + 1 < prevDay) {  obj.type = 'disabled'  }  } else if (this.nextYearMonthBoolean) {  let nextDay = this.nextDate.split('-')[2]  if (i + 1 > nextDay) {  obj.type = 'disabled'  }  }  calendarDateList.push(obj); } nextNum = 6 - new Date(year, month + 1, 0).getDay() // 當前月份最后一天的自然周剩余日期,置空 for (let i = 0; i < nextNum; i++) {  let obj = {  type: 'next',  content: ''  };  calendarDateList.push(obj); } return calendarDateList; }, // 設置日期 setContent (content) { if (!content) return '' return `${this.selectedYear}-${this.tf(this.selectedMonth + 1)}-${this.tf(content)}` === this.today ? '今天' : content }, // '今天'樣式開關 todayStyle (content) { if (!content) return false // Toast(`${this.selectedYear}-${this.tf(this.selectedMonth + 1)}-${this.tf(content)}`) return `${this.selectedYear}-${this.tf(this.selectedMonth + 1)}-${this.tf(content)}` === this.today }, // 當前選中的日期樣式開關 selectedDateStyle (content) { if (!content) return false return `${this.selectedYear}-${this.selectedMonth + 1}-${content}` === this.selectedFullDate },
// src/config/utils.js// 公共方法/** * @param AddDayCount 必傳 今天前后N天的日期 * @param dateStr: 非必傳 獲取傳入日期前后N天的日期:'2018-01-20' * @param type 非必傳 'lhRili'類型格式如'2018-7-3' * @return 返回日期'2018/01/20' */export const getDateStr = (AddDayCount, dateStr, type) => { // console.log('getDateStr', AddDayCount, dateStr, type) var dd if (!dateStr) { dd = new Date() } else { // 判斷是否為IOS const isIOS = !!navigator.userAgent.match(//(i[^;]+;( U;)? CPU.+Mac OS X/); let formatDateStr = isIOS ? dateStr.replace(/-/g, '/') : dateStr dd = new Date((formatDateStr.length < 12) ? formatDateStr + ' 00:00:00' : formatDateStr) } dd.setDate(dd.getDate() + AddDayCount) // 獲取AddDayCount天后的日期 let y = dd.getFullYear() let m let d if (type === 'lhRili') { m = dd.getMonth() + 1 d = dd.getDate() } else { let currentMon = (dd.getMonth() + 1) let getDate = dd.getDate() m = currentMon < 10 ? '0' + currentMon : currentMon // 獲取當前月份的日期,不足10補0 d = getDate < 10 ? '0' + getDate : getDate // 獲取當前幾號,不足10補0 } let time = y + '-' + m + '-' + d return time}

左右觸摸滑動事件 判斷是否月份還可以繼續滑動

// calendar.vue// 上一個月 handlePreMonth() { if (this.prevYearMonthBoolean) {  return } if (this.selectedMonth === 0) {  this.selectedYear = this.selectedYear - 1  this.selectedMonth = 11  this.selectedDate = 1 } else {  this.selectedMonth = this.selectedMonth - 1  this.selectedDate = 1 } }, // 下一個月 handleNextMonth() { if (this.nextYearMonthBoolean) {  return } if (this.selectedMonth === 11) {  this.selectedYear = this.selectedYear + 1  this.selectedMonth = 0  this.selectedDate = 1 } else {  this.selectedMonth = this.selectedMonth + 1  this.selectedDate = 1 } },

vuex存儲數據

// src/store/schedule.jsconst schedule = { state: { selectedDate: '', // 手動點擊選中的日期 currentDate: '' // 服務器當前日期 }, getters: { getSelectedDate: state => state.selectedDate, getCurrentDate: state => state.currentDate }, mutations: { SET_SELECTED_DATE: (state, data) => { state.selectedDate = data }, SET_CURRENT_DATE: (state, data) => { state.currentDate = data } }, actions: { setSelectedDate: ({ commit }, data) => commit('SET_SELECTED_DATE', data), setCurrentDate: ({ commit }, data) => commit('SET_CURRENT_DATE', data) }};export default schedule;

clickOutSide指令 指令方法監聽

// src/directive/click-out-side.jsexport default{ bind (el, binding, vnode) { function documentHandler (e) { if (el.contains(e.target)) { return false; } if (binding.expression) { binding.value(e); } } el.__vueClickOutside__ = documentHandler; document.addEventListener('click', documentHandler); }, unbind (el, binding) { document.removeEventListener('click', el.__vueClickOutside__); delete el.__vueClickOutside__; }}

注冊指令

// src/directive/index.jsimport clickOutSide from './click-out-side'const install = function (Vue) { Vue.directive('click-outside', clickOutSide)}if (window.Vue) { window.clickOutSide = clickOutSide Vue.use(install); // eslint-disable-line}clickOutSide.install = installexport default clickOutSide
// src/main.jsimport clickOutSide from '@/directive/click-out-side/index'Vue.use(clickOutSide)

使用方式:當某節點外部需要觸發事件時,掛載到該節點上

// calendar.vue<div class="cp-calendar" v-click-outside="spaceClick">....</div>

這里需要使用 fastclick 庫來消除解決移動端點擊事件300ms延時

// src/mian.jsimport FastClick from 'fastclick' // 在移動端,手指點擊一個元素,會經過:touchstart --> touchmove -> touchend --> click。FastClick.attach(document.body);

mock數據

// src/mock/index.js// mock數據入口import Mock from 'mockjs'import currentTime from './currentTime'// 攔截接口請求Mock.mock(///schedule//getCurrentTime/, 'get', currentTime)export default Mock// src/mock/currentTime.jsimport Mock from 'mockjs'export default { getList: () => { return { 'status': 'true', 'code': '200', 'msg': null, 'info': { 'currentDate': '2018-09-02' } } }}// src/main.js// 開發環境引入mockif (process.env.NODE_ENV === 'development') { require('./mock') // 需要在這里引入mock數據才可以全局攔截請求}

坑點

  • 在微信內置瀏覽器中,ios的日期格式跟安卓的日期格式分別是:YY/MM/DD和YY-MM-DD。這里需要對微信內置瀏覽器User Agent進行判斷。
  • 獲取服務器時間的異步問題,把獲取到的服務器時間保存在vuex里面,在calendar.vue頁面監聽當前日期的變化。及時將日歷數據計算渲染出來。

推薦:

感興趣的朋友可以關注小編的微信公眾號【碼農那點事兒】,更多網頁制作特效源碼及學習干貨哦!??!

總結

以上所述是小編給大家介紹的vue實現一個炫酷的日歷組件,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩中文字幕在线看| 91精品国产高清| 中文字幕综合一区| 精品一区二区三区四区| 日韩精品免费视频| 国产91精品不卡视频| www.亚洲成人| 亚洲美女av在线| 91国内在线视频| 亚洲美女视频网站| 色久欧美在线视频观看| 国产精品永久在线| 爽爽爽爽爽爽爽成人免费观看| 欧美第一页在线| 亚洲国产小视频在线观看| 国产成人一区二区在线| 久久免费国产精品1| 亚洲嫩模很污视频| 国产成人精品av在线| 日韩在线视频观看正片免费网站| 九九热精品在线| 亚洲视频视频在线| 国产噜噜噜噜噜久久久久久久久| 91精品国产自产在线观看永久| 亚洲欧洲xxxx| 久久久精品国产亚洲| 欧美性受xxxx白人性爽| 国产一区二区三区四区福利| 亚洲精品日韩丝袜精品| 精品美女久久久久久免费| 欧美精品久久久久久久久久| 欧美激情第99页| 美女999久久久精品视频| 亚洲精品电影在线观看| 久久九九有精品国产23| 亚洲成色999久久网站| 精品成人国产在线观看男人呻吟| 一区二区亚洲欧洲国产日韩| 亚洲a∨日韩av高清在线观看| 国产在线播放不卡| 日韩动漫免费观看电视剧高清| 91热精品视频| 欧美一级片久久久久久久| 欧洲成人在线观看| 国产精品日韩欧美综合| 久久久精品日本| 国产精品久久久久久久久久久不卡| 亚洲福利在线播放| 97久久精品视频| 久久精品青青大伊人av| 一本色道久久88亚洲综合88| 亚洲自拍中文字幕| 性日韩欧美在线视频| 美日韩精品免费观看视频| 亚洲色图综合久久| 亚洲国产毛片完整版| 成人97在线观看视频| 欧美孕妇与黑人孕交| 亚洲精品国产精品乱码不99按摩| 亚洲精美色品网站| 日韩a**站在线观看| 国内伊人久久久久久网站视频| 国产91久久婷婷一区二区| 国产成人免费91av在线| 国产精品女主播视频| 国产精品99导航| 国产精品美女www爽爽爽视频| 日韩电影中文 亚洲精品乱码| 国产精品va在线播放| 98精品国产高清在线xxxx天堂| 欧美日韩精品中文字幕| 国产精品影片在线观看| 国产精品午夜一区二区欲梦| 91在线视频精品| 视频在线一区二区| 久久91超碰青草是什么| 国产欧美中文字幕| 亚洲成人网在线观看| 欧美制服第一页| 日韩在线视频国产| 日韩欧美精品在线观看| 91天堂在线视频| 国内伊人久久久久久网站视频| 在线看片第一页欧美| 色综合色综合网色综合| 国产精品入口免费视频一| 欧美日韩国产成人在线观看| 亚洲美女av电影| 欧美成人中文字幕在线| 欧美精品久久久久久久免费观看| 国a精品视频大全| 91免费福利视频| 狠狠躁天天躁日日躁欧美| 久久精品久久久久久| 日韩中文字幕网址| 尤物99国产成人精品视频| 国产欧美一区二区三区在线| 成人精品久久av网站| 亚洲欧美在线一区二区| 一区二区三区回区在观看免费视频| 久久久精品国产网站| 国产91精品青草社区| 黑人狂躁日本妞一区二区三区| 精品一区二区亚洲| 亚洲a中文字幕| 91九色视频导航| 欧美激情精品久久久久久免费印度| 日韩在线视频一区| 欧美精品18videos性欧| 色老头一区二区三区在线观看| 欧美日韩午夜剧场| 国产精品国产三级国产aⅴ9色| 欧美午夜影院在线视频| 亚洲国内精品在线| 色七七影院综合| 成人网在线观看| 亚洲男人天堂视频| 久久成人人人人精品欧| 久久国产精品免费视频| 91国偷自产一区二区三区的观看方式| 91在线精品视频| 亚洲欧美一区二区三区久久| 亚洲无线码在线一区观看| 欧美床上激情在线观看| 国产伦精品免费视频| 欧美日韩在线观看视频小说| 亚洲欧美综合区自拍另类| 亚洲综合av影视| 久久欧美在线电影| 国产69精品久久久久久| 久久国产加勒比精品无码| 日本欧美黄网站| 国产中文字幕亚洲| 国产精品日韩在线播放| 欧美在线不卡区| 精品亚洲一区二区三区在线观看| 91久久精品在线| 亚洲午夜精品久久久久久性色| 2019中文字幕在线免费观看| 国产精品视频久久久| 欧美高清videos高潮hd| 国产精品96久久久久久又黄又硬| 亚洲情综合五月天| 国产精品va在线播放我和闺蜜| 日韩美女写真福利在线观看| 亚洲激情视频在线| 国产精品久久久久久久美男| 在线观看国产精品91| 日韩精品视频在线观看免费| 国产一区二区日韩精品欧美精品| 久久久在线视频| 美日韩精品免费视频| 欧美日韩高清区| 一本一道久久a久久精品逆3p| 久久久亚洲成人| 伊人久久综合97精品| 亚洲男人天堂2019| 欧美xxxx做受欧美.88| 亚洲无限av看| 97香蕉久久夜色精品国产| 国产精品成人av性教育| 一区二区欧美日韩视频| 欧美日韩加勒比精品一区| 欧美大片在线免费观看|