亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

vue實現(xiàn)一個炫酷的日歷組件

 更新時間:2018年10月08日 11:50:22   作者:Kellercai  
公司業(yè)務新開了一個商家管理微信H5移動端項目,日歷控件是商家管理員查看通過日程來篩選獲取某日用戶的訂單等數(shù)據(jù)。下面小編給大家?guī)砹嘶趘ue實現(xiàn)一個炫酷的日歷組件,感興趣的朋友參考下吧

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


90天前:


90天后;

產(chǎn)品需求:

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

涉及內(nèi)容:

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

開發(fā):

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

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

日歷展盤

// 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>

初始化數(shù)據(jù) 針對服務器時間進行初始數(shù)據(jù)處理

// calendar.vue
// 設置初始數(shù)據(jù)
 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) {
 // 定義每個月的天數(shù),如果是閏年第二月改為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
}

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

// 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存儲數(shù)據(jù)

// src/store/schedule.js
const 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指令 指令方法監(jiān)聽

// src/directive/click-out-side.js
export 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.js
import 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 = install
export default clickOutSide
// src/main.js
import clickOutSide from '@/directive/click-out-side/index'

Vue.use(clickOutSide)

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

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

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

// src/mian.js
import FastClick from 'fastclick' // 在移動端,手指點擊一個元素,會經(jīng)過:touchstart --> touchmove -> touchend --> click。

FastClick.attach(document.body);

mock數(shù)據(jù)

// src/mock/index.js
// mock數(shù)據(jù)入口
import Mock from 'mockjs'
import currentTime from './currentTime'

// 攔截接口請求
Mock.mock(/\/schedule\/getCurrentTime/, 'get', currentTime)

export default Mock
// src/mock/currentTime.js
import Mock from 'mockjs'

export default {
 getList: () => {
 return {
 'status': 'true',
 'code': '200',
 'msg': null,
 'info': {
 'currentDate': '2018-09-02'
 }
 }
 }
}
// src/main.js
// 開發(fā)環(huán)境引入mock
if (process.env.NODE_ENV === 'development') {
 require('./mock') // 需要在這里引入mock數(shù)據(jù)才可以全局攔截請求
}

坑點

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

推薦:

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

總結

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

相關文章

  • vue高德地圖繪制行政區(qū)邊界功能

    vue高德地圖繪制行政區(qū)邊界功能

    這篇文章主要介紹了vue高德地圖繪制行政區(qū)邊界功能,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧
    2024-03-03
  • Vue實現(xiàn)五子棋小游戲

    Vue實現(xiàn)五子棋小游戲

    這篇文章主要為大家詳細介紹了Vue實現(xiàn)五子棋小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • vue中的計算屬性實例詳解

    vue中的計算屬性實例詳解

    模板內(nèi)的表達式非常便利,但是設計它們的初衷是用于簡單運算的。接下來通過本文給大家介紹vue中的計算屬性,需要的朋友可以參考下
    2018-09-09
  • vueCli?4.x升級5.x報錯:Progress?Plugin?Invalid?Options的解決方法

    vueCli?4.x升級5.x報錯:Progress?Plugin?Invalid?Options的解決方法

    本文主要介紹了vueCli?4.x升級5.x報錯:Progress?Plugin?Invalid?Options的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • vue頁面渲染數(shù)組中數(shù)據(jù)文案后添加逗號最后不加

    vue頁面渲染數(shù)組中數(shù)據(jù)文案后添加逗號最后不加

    這篇文章主要為大家介紹了vue頁面渲染數(shù)組中數(shù)據(jù)文案后添加逗號最后不加逗號示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • Vue3+TypeScript+printjs實現(xiàn)標簽批量打印功能的完整過程

    Vue3+TypeScript+printjs實現(xiàn)標簽批量打印功能的完整過程

    最近在做vue項目時使用到了print-js打印,這里給大家分享下,這篇文章主要給大家介紹了關于Vue3+TypeScript+printjs實現(xiàn)標簽批量打印功能的完整過程,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-09-09
  • vue router點擊打開新的標簽頁的方法(最新推薦)

    vue router點擊打開新的標簽頁的方法(最新推薦)

    vue router點擊打開新的標簽頁的方法,只需要在router-link中加入target="_blank"即可在新的頁面打開標簽,本文通過實例代碼給大家介紹的非常詳細,需要的朋友參考下吧
    2023-10-10
  • vue添加class樣式實例講解

    vue添加class樣式實例講解

    在本文里我們給大家整理了關于vue添加class樣式實例,對此有興趣的朋友們可以學習參考下。
    2019-02-02
  • vue中實現(xiàn)回車鍵登錄功能

    vue中實現(xiàn)回車鍵登錄功能

    這篇文章主要介紹了vue中實現(xiàn)回車鍵登錄功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • axios中cookie跨域及相關配置示例詳解

    axios中cookie跨域及相關配置示例詳解

    自從入了 Vue 之后,一直在用 axios 這個庫來做一些異步請求。下面這篇文章主要給大家介紹了關于axios中cookie跨域及相關配置的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起看看吧。
    2017-12-12

最新評論