欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于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、可以自己控制展開收起 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),同時(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ò)類名判斷當(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)閉合范圍,也可能是第一次打開點(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)文章

  • vue中如何動(dòng)態(tài)設(shè)置css樣式的hover

    vue中如何動(dòng)態(tài)設(shè)置css樣式的hover

    這篇文章主要介紹了vue中如何動(dòng)態(tài)設(shè)置css樣式的hover,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue-cli-service的參數(shù)配置過(guò)程

    vue-cli-service的參數(shù)配置過(guò)程

    這篇文章主要介紹了vue-cli-service的參數(shù)配置過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 關(guān)于Nuxt的五種渲染模式的差異和使用場(chǎng)景全解析

    關(guān)于Nuxt的五種渲染模式的差異和使用場(chǎng)景全解析

    這篇文章主要介紹了關(guān)于Nuxt的五種渲染模式的差異和使用場(chǎng)景全解析,在過(guò)去傳統(tǒng)開發(fā)中,頁(yè)面渲染任務(wù)是由服務(wù)端完成的,那么Nuxt是如何渲染的呢,需要的朋友可以參考下
    2023-04-04
  • Vue中CSS?scoped的原理詳細(xì)講解

    Vue中CSS?scoped的原理詳細(xì)講解

    在組件中增加的css加了scoped屬性之后,就在會(huì)在當(dāng)前這個(gè)組件的節(jié)點(diǎn)上增加一個(gè)data-v-xxx屬性,下面這篇文章主要給大家介紹了關(guān)于Vue中CSS?scoped原理的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • element-plus+Vue3實(shí)現(xiàn)表格數(shù)據(jù)動(dòng)態(tài)渲染

    element-plus+Vue3實(shí)現(xiàn)表格數(shù)據(jù)動(dòng)態(tài)渲染

    在Vue中,el-table是element-ui提供的強(qiáng)大表格組件,可以用于展示靜態(tài)和動(dòng)態(tài)表格數(shù)據(jù),本文主要介紹了element-plus+Vue3實(shí)現(xiàn)表格數(shù)據(jù)動(dòng)態(tài)渲染,感興趣的可以了解一下
    2024-03-03
  • vue前端開發(fā)輔助函數(shù)狀態(tài)管理詳解示例

    vue前端開發(fā)輔助函數(shù)狀態(tài)管理詳解示例

    vue的應(yīng)用狀態(tài)管理提供了mapState、mapGetters、mapMutations、mapActions四個(gè)輔助函數(shù),所謂的輔助函數(shù)分別對(duì)State、Getters、Mutations、Actions在完成狀態(tài)的使用進(jìn)行簡(jiǎn)化
    2021-10-10
  • vue.js $refs和$emit 父子組件交互的方法

    vue.js $refs和$emit 父子組件交互的方法

    本篇文章主要介紹了vue.js $refs和$emit 父子組件交互的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • 使用Vue動(dòng)態(tài)生成form表單的實(shí)例代碼

    使用Vue動(dòng)態(tài)生成form表單的實(shí)例代碼

    這篇文章主要介紹了使用Vue動(dòng)態(tài)生成form表單的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-04-04
  • vue工程全局設(shè)置ajax的等待動(dòng)效的方法

    vue工程全局設(shè)置ajax的等待動(dòng)效的方法

    這篇文章主要介紹了vue工程全局設(shè)置ajax的等待動(dòng)效的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • 用electron 打包發(fā)布集成vue2.0項(xiàng)目的操作過(guò)程

    用electron 打包發(fā)布集成vue2.0項(xiàng)目的操作過(guò)程

    這篇文章主要介紹了用electron 打包發(fā)布集成vue2.0項(xiàng)目的操作步驟,把electron 加入到自己項(xiàng)目中各種不兼容,升級(jí)版本踩坑無(wú)數(shù)個(gè),今天通過(guò)本文給大家分享下詳細(xì)過(guò)程,需要的朋友可以參考下
    2022-10-10

最新評(píng)論