最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Vue實(shí)現(xiàn)可選擇不連續(xù)的時(shí)間范圍的日期選擇器

 更新時(shí)間:2023年06月04日 11:01:14   作者:局部變量  
這篇文章主要為大家詳細(xì)介紹了如何基于Vue.js實(shí)現(xiàn)一個(gè)可選擇不連續(xù)的時(shí)間范圍的日期選擇器,文中的示例代碼簡(jiǎn)潔易懂,需要的可以參考一下

省流:

npm包:sta-datepicker

效果圖

需求

普通的時(shí)間選擇器要么只能單選,要么只能選范圍,不可以隨意選擇若干個(gè)時(shí)間,同時(shí)大多數(shù)現(xiàn)成的時(shí)間選擇器選擇結(jié)束會(huì)收起來(lái),很不方便?,F(xiàn)在需求如下 1、可以自己控制展開(kāi)收起 2、可以選擇不連續(xù)的多個(gè)時(shí)間范圍的日期 3、可以批量選中日期,不需要一個(gè)個(gè)點(diǎn)擊

實(shí)現(xiàn)過(guò)程

分幾個(gè)步驟,具體可以看源碼

1、生成一個(gè)日歷

頂部為固定的幾個(gè)按鈕,可以綁定切換年份月份的函數(shù)

中間為固定的星期,一個(gè)七個(gè)

底部為具體日期,由三部分組成,即:上個(gè)月底幾天,這個(gè)月整個(gè)月,下個(gè)月初幾天

  • 算好平年閏年,輸出當(dāng)前月份第一天是周幾
  • 根據(jù)當(dāng)前月份的第一天的星期數(shù),計(jì)算日歷要展示上個(gè)月月底的幾天
  • 根據(jù)當(dāng)前月份最后一天的星期數(shù),計(jì)算日歷要展示下個(gè)月月初的幾天

日期部分使用div遍歷三個(gè)數(shù)組,左浮動(dòng)或者彈性盒直接堆起來(lái)即可

  created() {
    this.trueDateBox()
  },
  methods: {
    trueDateBox() {
      if (this.date === "") {
        const date = new Date()
        this.year = date.getFullYear()
        this.updateLeapYear()
        this.month = date.getMonth() + 1
        this.day = null
      }
      this.dayScreen()
    },
    // 設(shè)置算好閏年平年
    updateLeapYear() {
      if (this.isLeapYear(this.year)) {
        this.monthDay[1] = 29
      } else {
        this.monthDay[1] = 28
      }
    },
    isLeapYear(year) {
      return year % 100 === 0 ? year % 400 === 0 : year % 4 === 0
    },
    // 日期顯示
    dayScreen() {
      // 渲染上個(gè)月,第一行
      const firstDate = new Date(this.year, this.month - 1, 1)
      const firstWeek = firstDate.getDay()
      let preMonthDay = null
      if (this.month === 1) {
        preMonthDay = this.monthDay[11]
      } else {
        preMonthDay = this.monthDay[this.month - 2]
      }
      console.log("preMonthDay", this.monthDay[11], this.month)
      for (let i = 0; i < preMonthDay; i++) {
        this.previousMonth[i] = i + 1
      }
      if (firstWeek === 0) {
        this.previousMonth = this.previousMonth.slice(-7)
      } else {
        this.previousMonth = this.previousMonth.slice(-firstWeek)
        console.log(33, this.previousMonth)
      }
      // 渲染下個(gè)月, 最后一行
      const endDate = new Date(
        this.year,
        this.month - 1,
        this.monthDay[this.month - 1]
      )
      const endWeek = endDate.getDay()
      let nextMonthDay = null
      if (this.month === 12) {
        nextMonthDay = this.monthDay[0]
      } else {
        nextMonthDay = this.monthDay[this.month]
      }
      for (let i = 0; i < nextMonthDay; i++) {
        this.nextMonth[i] = i + 1
      }
      if (endWeek === 6) {
        this.nextMonth = this.nextMonth.slice(0, 7)
      } else {
        this.nextMonth = this.nextMonth.slice(0, 6 - endWeek)
      }
    },
  }

2、綁定四個(gè)固定的函數(shù)

點(diǎn)擊上一年,下一年,上個(gè)月,下個(gè)月時(shí),需要計(jì)算跨年的情況

    // 年份的增減
    addYear() {
      this.year++
      this.updateLeapYear()
    },
    reduceYear() {
      this.year--
      this.updateLeapYear()
    },
    // 月份的增減
    addMonth() {
      this.month++
      if (this.month > 12) {
        this.month = 1
        this.addYear()
      }
    },
    reduceMonth() {
      this.month--
      if (this.month < 1) {
        this.month = 12
        this.reduceYear()
      }
    },

3、點(diǎn)擊具體日期時(shí),確定狀態(tài)

使用數(shù)組存起當(dāng)前已選的日期,使用一個(gè)變量記錄當(dāng)前半選的日期

通過(guò)一個(gè)函數(shù)isActive給每個(gè)日期綁定類(lèi)名,從而在視圖上顯示出來(lái),同時(shí)可以確定狀態(tài)的切換

  • 如果點(diǎn)擊了已選日期的數(shù)據(jù),需要剔除,改為空白狀態(tài)
  • 如果點(diǎn)擊了半選態(tài)日期,則直接選中當(dāng)前日期,變?yōu)橐堰x日期
  • 如果點(diǎn)擊了空白狀態(tài)日期,則可能有兩種情況,一是已存在半選態(tài)日期,等待閉合,而是不存在半選態(tài)日期,當(dāng)前設(shè)置為半選
methods: {
    // 突出顯示當(dāng)前日期
    isActive(index) {
      const date = new Date()
      const y = date.getFullYear()
      const m = date.getMonth() + 1
      const d = date.getDate()
      const obj = {}
      if (this.year === y && this.month === m && index === d) {
        obj.today = true
      }
      const newIndexStr = index < 10 ? `0${index}` : `${index}`
      const newMonthStr = this.month < 10 ? `0${this.month}` : `${this.month}`
      const item = `${this.year}/${newMonthStr}/${newIndexStr}`
      if (item === this.partialSelect) {
        obj.active = true
      }
      if (this.selctDate.includes(item)) {
        obj.activeRange = true
      }
      return obj
    },
    selectDay(e, type) {
      const iText = e.target.innerText
      const sDate = Number(iText) < 10 ? `0${iText}` : `${iText}`
      if (type === "previousMonth") {
        if (this.month === 1) {
          this.month = 12
          this.reduceYear()
        } else {
          this.month = this.month - 1
        }
      } else if (type === "nextMonth") {
        if (this.month === 12) {
          this.month = 1
          this.addYear()
        } else {
          this.month = this.month + 1
        }
      }
      let arr = this.selctDate.map((i) => new Date(i).getTime())
      const newMonthStr = this.month < 10 ? `0${this.month}` : `${this.month}`
      const curSelectTime = `${this.year}/${newMonthStr}/${sDate}`
      const curSelectTimeStamp = new Date(curSelectTime).getTime()
      const clsName = e.target.className // 通過(guò)類(lèi)名判斷當(dāng)前是什么狀態(tài)
      if (clsName.includes("activeRange")) {
        // 點(diǎn)擊了范圍內(nèi)的數(shù)據(jù),需要剔除
        arr = arr.filter((i) => i !== curSelectTimeStamp)
      } else if (clsName.includes("active") && !clsName.includes("activeRange")) {
        // 點(diǎn)擊了一個(gè)半選狀態(tài)的日期,準(zhǔn)備擴(kuò)展范圍或者單選一個(gè)
        if (this.selctDate.length) {
          const itemTime = arr[0]
          const itemTime2 = arr[arr.length - 1]
          const selectTime = curSelectTimeStamp
          if (selectTime < itemTime) {
            console.log("點(diǎn)擊了范圍之前的時(shí)間")
          } else if (selectTime > itemTime2) {
            console.log("點(diǎn)擊了范圍之后的時(shí)間")
          } else {
            console.log("點(diǎn)擊了范圍內(nèi)的空白,直接加上一個(gè)")
          }
          arr = [...arr, curSelectTimeStamp]
          console.log(arr)
        } else {
          // 第一次選擇日期,而且雙擊了,直接單獨(dú)確定這個(gè)
          arr = [curSelectTimeStamp]
        }
        // 此時(shí)選擇完日前了,半選的日期消費(fèi)掉了,清空
        this.partialSelect = null
      } else {
        console.log("不是半選情況")
        // 即沒(méi)有點(diǎn)擊范圍內(nèi),又不是半選狀態(tài),可能是已經(jīng)存在一個(gè)半選,等待這個(gè)日期來(lái)閉合范圍,也可能是第一次打開(kāi)點(diǎn)擊
        if (this.partialSelect) {
          // 需要和已存在的半選態(tài)日期閉合
          const itemTime = new Date(this.partialSelect).getTime()
          const itemTime2 = curSelectTimeStamp
          const timeArr = [itemTime, itemTime2].sort((a, b) => a - b) // 排序,因?yàn)椴恢勒l(shuí)在前面
          for (let i = timeArr[0]; i <= timeArr[1]; i += 86400000) {
            arr.push(i)
          }
          // 此時(shí)確定好范圍了,半選的日期消費(fèi)掉了,清空
          this.partialSelect = null
        } else if (this.selctDate.length) {
          // 存在一個(gè)范圍,同時(shí)點(diǎn)擊范圍外,此時(shí)設(shè)置半選
          this.day = sDate
          this.partialSelect = curSelectTime
        } else {
          // 不存在一個(gè)范圍,所以是第一次點(diǎn)擊
          this.day = sDate
          this.partialSelect = curSelectTime
        }
      }
      let filterArr = Array.from(new Set(arr))
      filterArr = filterArr.sort((a, b) => a - b)
      this.selctDate = filterArr.map((i) => this.formatTime(new Date(i)))
      this.$emit("input", this.selctDate)
      this.$emit("change", this.selctDate)
      this.day = parseInt(sDate)
    },
}

以上就是基于Vue實(shí)現(xiàn)可選擇不連續(xù)的時(shí)間范圍的日期選擇器的詳細(xì)內(nèi)容,更多關(guān)于Vue日期選擇器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 關(guān)于vant折疊面板默認(rèn)展開(kāi)問(wèn)題

    關(guān)于vant折疊面板默認(rèn)展開(kāi)問(wèn)題

    這篇文章主要介紹了關(guān)于vant折疊面板默認(rèn)展開(kāi)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue實(shí)現(xiàn)select下拉顯示隱藏功能

    vue實(shí)現(xiàn)select下拉顯示隱藏功能

    這篇文章主要介紹了vue實(shí)現(xiàn)select下拉顯示隱藏功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • vue router點(diǎn)擊打開(kāi)新的標(biāo)簽頁(yè)的方法(最新推薦)

    vue router點(diǎn)擊打開(kāi)新的標(biāo)簽頁(yè)的方法(最新推薦)

    vue router點(diǎn)擊打開(kāi)新的標(biāo)簽頁(yè)的方法,只需要在router-link中加入target="_blank"即可在新的頁(yè)面打開(kāi)標(biāo)簽,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-10-10
  • Vue中使用 setTimeout() setInterval()函數(shù)的問(wèn)題

    Vue中使用 setTimeout() setInterval()函數(shù)的問(wèn)題

    這篇文章主要介紹了Vue中使用 setTimeout() setInterval()函數(shù)的問(wèn)題 ,需要的朋友可以參考下
    2018-09-09
  • 詳細(xì)解讀VUE父子組件的使用

    詳細(xì)解讀VUE父子組件的使用

    這篇文章主要介紹了詳細(xì)解讀VUE父子組件的使用,今天來(lái)講一種子父組件深度耦合的方式,使我們不用額外的創(chuàng)建新的組件,也可以達(dá)到一些效果,下面與你們分享一下
    2023-05-05
  • Vue組件之間的通信方式詳細(xì)講解

    Vue組件之間的通信方式詳細(xì)講解

    對(duì)于vue來(lái)說(shuō),組件之間的消息傳遞是非常重要的,用vue可以是要組件復(fù)用的,而組件實(shí)例的作用域是相互獨(dú)立,這意味著不同組件之間的數(shù)據(jù)無(wú)法互相引用,一般來(lái)說(shuō),組件之間可以有幾種關(guān)系,下面是我對(duì)組件之間消息傳遞的常用方式的總結(jié)
    2022-08-08
  • vue+django實(shí)現(xiàn)一對(duì)一聊天功能的實(shí)例代碼

    vue+django實(shí)現(xiàn)一對(duì)一聊天功能的實(shí)例代碼

    這篇文章主要介紹了vue+django實(shí)現(xiàn)一對(duì)一聊天功能,主要是通過(guò)websocket,由于Django不支持websocket,所以我使用了django-channels。,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2019-07-07
  • vue將后臺(tái)數(shù)據(jù)時(shí)間戳轉(zhuǎn)換成日期格式

    vue將后臺(tái)數(shù)據(jù)時(shí)間戳轉(zhuǎn)換成日期格式

    這篇文章主要為大家詳細(xì)介紹了vue將后臺(tái)數(shù)據(jù)時(shí)間戳轉(zhuǎn)換成日期格式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • vue實(shí)現(xiàn)短信驗(yàn)證碼輸入框

    vue實(shí)現(xiàn)短信驗(yàn)證碼輸入框

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)短信驗(yàn)證碼輸入框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 頁(yè)面刷新后Vuex狀態(tài)丟失的完整解決方案

    頁(yè)面刷新后Vuex狀態(tài)丟失的完整解決方案

    當(dāng)頁(yè)面刷新時(shí),Vuex?的?state?數(shù)據(jù)會(huì)丟失,這是因?yàn)?Vuex?的狀態(tài)存儲(chǔ)在內(nèi)存中,刷新瀏覽器會(huì)重置?JavaScript?的運(yùn)行環(huán)境,下面我將詳細(xì)介紹幾種解決方案,從簡(jiǎn)單到復(fù)雜,幫助你根據(jù)項(xiàng)目需求選擇最適合的方法,需要的朋友可以參考下
    2025-04-04

最新評(píng)論

永胜县| 化隆| 宁河县| 太谷县| 阳西县| 邵东县| 朝阳区| 廊坊市| 太仓市| 屏南县| 南陵县| 青冈县| 温州市| 微山县| 武隆县| 兴山县| 调兵山市| 临朐县| 杭锦后旗| 军事| 淅川县| 驻马店市| 新乐市| 常山县| 罗平县| 新竹县| 垫江县| 酒泉市| 固始县| 自贡市| 道真| 牡丹江市| SHOW| 柘荣县| 南阳市| 资阳市| 兴海县| 绩溪县| 平度市| 桐柏县| 闽侯县|