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

el-date-picker日期范圍限制的實(shí)現(xiàn)

 更新時(shí)間:2023年05月06日 09:01:05   作者:class良木  
本文主要介紹了el-date-picker日期范圍限制的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

最近遇到一個(gè)需求:需要限制報(bào)表下載的日期范圍,統(tǒng)一為半個(gè)月,防止用戶選擇范圍過(guò)廣,導(dǎo)致報(bào)表生成緩慢。

項(xiàng)目中使用的element-ui的el-date-picker日期選擇組件。

實(shí)現(xiàn)思路

  • 1.由于頁(yè)面中有12處需要修改,所以需要對(duì)el-date-picker進(jìn)行二次封裝。
  • 2.el-date-picker提供的picker-options中的disabledDate屬性可以對(duì)可選日期進(jìn)行動(dòng)態(tài)禁用與啟用。
  • 3.disabledDate屬性只能針對(duì)選擇日期的情況,當(dāng)用戶手動(dòng)輸入日期時(shí),需要進(jìn)行攔截處理。

具體實(shí)現(xiàn)

聲明了全局組件HalfMonthPicker

組件模板定義

組件中使用v-bind="attrs"和v−on="attrs"和v-on="attrs"和v−on="listeners"進(jìn)行了屬性和事件透?jìng)?,方便后期維護(hù)。

<el-date-picker
    v-bind="$attrs"
    v-on="$listeners"
    :type="type"
    :range-separator="rangeSeparator"
    :start-placeholder="startPlaceholder"
    :end-placeholder="endPlaceholder"
    :value="value"
    :picker-options="pickerOptions"></el-date-picker>

定義props屬性 type

el-date-picker目前支持的范圍屬性為daterange和datetimerange,內(nèi)部使用了校驗(yàn)函數(shù),確保傳入的參數(shù)值,默認(rèn)為daterange。

props: {
    type: {
        type: String,
        default: 'daterange',
        validator(val) {
            return ['daterange', 'datetimerange'].includes(val)
        }
    }
}

設(shè)置默認(rèn)屬性值

由于頁(yè)面中組件使用時(shí)都傳入了自定義的range-separator,start-placeholder,和end-placeholder,其屬性值相同,所以在組件內(nèi)部定義了props,并設(shè)置了默認(rèn)值,避免頁(yè)面中重復(fù)定義。

props: {
    rangeSeparator: {
        type: String,
        default: '至'
    },
    startPlaceholder: {
        type: String,
        default: '起止日期'
    },
    endPlaceholder: {
        type: String,
        default: '截止日期'
    }
}

定義核心計(jì)算屬性pickerOptions

基本變量定義

currentFirstDate

首個(gè)選中的日期

currentFirstTime

首個(gè)選中的日期毫秒數(shù)

currentMinTime

小于currentFirstTime半個(gè)月的毫秒數(shù)

currentMaxTime

大于currentFirstTime半個(gè)月的毫秒數(shù)

currentTime

disabledDate函數(shù)傳入的日期值的毫秒數(shù),用于判斷是否在currentMinTime與currentMaxTime之間

shortcuts快捷選項(xiàng)

此處按照產(chǎn)品需求,內(nèi)置了最近一周和最近半個(gè)月的快捷選項(xiàng)。

disabledDate實(shí)現(xiàn)

如果存在currentFirstDate,將小于半月或超出半月的日期置為不可選中。

如果不存在,則皆可選。

onPick注意事項(xiàng)

1.當(dāng)maxDate和minDate都不存在

將currentFirstDate置為null,不限制日期選擇

2.minDate存在,而maxDate不存在

currentFirstDate = minDate,并限制日期選擇為前后半個(gè)月

3.maxDate和minDate同時(shí)存在

考慮如下情況,type為datetimerange時(shí),即使選中了開(kāi)始日期和結(jié)束日期,如果沒(méi)有點(diǎn)確定,彈框并不會(huì)消失,此時(shí)應(yīng)該可以重新選擇新的開(kāi)始日期,所以需要將currentFirstDate置為null,不在限制日期的選擇。

未置為null

微信截圖_20230504171113.png

置為null 

微信截圖_20230504171129.png

computed: {
    pickerOptions() {
        const { value } = this
        // 選中的首個(gè)日期
        let currentFirstDate = Array.isArray(value) && value.length === 1 && value[0] ? value[0] : null
        // 選中的首個(gè)日期毫秒數(shù)
        let currentFirstTime = null
        // 當(dāng)前日期毫秒數(shù)
        let currentTime = null
        // 當(dāng)前可選最小日期毫秒數(shù)
        let currentMinTime = null
        // 當(dāng)前可選最大日期毫秒數(shù)
        let currentMaxTime = null
        return {
            // 快捷選項(xiàng)
            shortcuts: [
                {
                    text: '最近一周',
                    onClick(picker) {
                        const end = new Date()
                        const start = new Date()
                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 6)
                        picker.$emit('pick', [start, end])
                    }
                },
                {
                    text: '最近半月',
                    onClick(picker) {
                        const end = new Date()
                        const start = new Date()
                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 14)
                        picker.$emit('pick', [start, end])
                    }
                }
            ],
            // 禁選邏輯
            disabledDate(date) {
                if (currentFirstDate) {
                    currentFirstTime = new Date(currentFirstDate).getTime()
                    currentTime = new Date(date).getTime()
                    currentMinTime = currentFirstTime - 3600 * 1000 * 24 * 15
                    currentMaxTime = currentFirstTime + 3600 * 1000 * 24 * 15
                    // 確保當(dāng)前可選日期在半月之間
                    return !(currentTime > currentMinTime && currentTime < currentMaxTime)
                }
                return false
            },
            // 選中項(xiàng)
            onPick({ maxDate, minDate }) {
                // console.log(maxDate)
                currentFirstDate = !maxDate ? minDate : null
            }
        }
    }
}

處理手動(dòng)輸入的情況

考慮如下場(chǎng)景,當(dāng)用戶選擇在input框中手動(dòng)輸入日期時(shí),pickerOptions中的disabledDate禁選屬性便無(wú)法對(duì)用戶產(chǎn)生攔截作用,此時(shí)便需要通過(guò)監(jiān)聽(tīng)value屬性的變化,當(dāng)newVal間隔大于半個(gè)月時(shí),重置回oldVal。

微信截圖_20230504164206.png

watch: {
    // 處理手動(dòng)輸入的情況
    value: {
        handler(newVal, oldVal) {
            if (Array.isArray(newVal) && newVal.length === 2) {
                if (this.compareHalfMonthInterval(newVal[0], newVal[1])) {
                    this.$message.warning('日期間隔不能超過(guò)半個(gè)月')
                    // 重置為oldVal或null
                    this.$emit('input', oldVal || null)
                }
            }
        },
        immediate: true
    }
},
methods: {
    /**
     * 比較時(shí)間是否超出半個(gè)月
     * @param {*} startDate 開(kāi)始時(shí)間
     * @param {*} endDate 結(jié)束時(shí)間
     * @returns { boolean } true為超出半個(gè)月
     */
    compareHalfMonthInterval(startDate, endDate) {
        if (!startDate || !endDate) {
            return false
        }
        const startTime = new Date(startDate).getTime()
        const endTime = new Date(endDate).getTime()
        return (endTime - startTime) > 3600 * 1000 * 24 * 15
    }
}

頁(yè)面中使用

使用前

微信截圖_20230504165349.png

微信截圖_20230504165518.png

使用后 

微信截圖_20230504165441.png

微信截圖_20230504165558.png

使用效果

選擇開(kāi)始日期

微信截圖_20230504190215.png

選擇結(jié)束日期 

微信截圖_20230504190232.png

完整代碼實(shí)現(xiàn)

<template>
    <el-date-picker
        v-bind="$attrs"
        v-on="$listeners"
        :type="type"
        :range-separator="rangeSeparator"
        :start-placeholder="startPlaceholder"
        :end-placeholder="endPlaceholder"
        :value="value"
        :picker-options="pickerOptions"></el-date-picker>
</template>
<script>
export default {
    name: 'HalfMonthPicker',
    props: {
        type: {
            type: String,
            default: 'daterange',
            validator(val) {
                return ['daterange', 'datetimerange'].includes(val)
            }
        },
        value: {
            type: Array,
            default: () => []
        },
        rangeSeparator: {
            type: String,
            default: '至'
        },
        startPlaceholder: {
            type: String,
            default: '起止日期'
        },
        endPlaceholder: {
            type: String,
            default: '截止日期'
        }
    },
    computed: {
        pickerOptions() {
            const { value } = this
            // 選中的首個(gè)日期
            let currentFirstDate = Array.isArray(value) && value.length === 1 && value[0] ? value[0] : null
            // 選中的首個(gè)日期毫秒數(shù)
            let currentFirstTime = null
            // 當(dāng)前日期毫秒數(shù)
            let currentTime = null
            // 當(dāng)前可選最小日期毫秒數(shù)
            let currentMinTime = null
            // 當(dāng)前可選最大日期毫秒數(shù)
            let currentMaxTime = null
            return {
                // 快捷選項(xiàng)
                shortcuts: [
                    {
                        text: '最近一周',
                        onClick(picker) {
                            const end = new Date()
                            const start = new Date()
                            start.setTime(start.getTime() - 3600 * 1000 * 24 * 6)
                            picker.$emit('pick', [start, end])
                        }
                    },
                    {
                        text: '最近半月',
                        onClick(picker) {
                            const end = new Date()
                            const start = new Date()
                            start.setTime(start.getTime() - 3600 * 1000 * 24 * 14)
                            picker.$emit('pick', [start, end])
                        }
                    }
                ],
                // 禁選邏輯
                disabledDate(date) {
                    if (currentFirstDate) {
                        currentFirstTime = new Date(currentFirstDate).getTime()
                        currentTime = new Date(date).getTime()
                        currentMinTime = currentFirstTime - 3600 * 1000 * 24 * 15
                        currentMaxTime = currentFirstTime + 3600 * 1000 * 24 * 15
                        // 確保當(dāng)前可選日期在半月之間
                        return !(currentTime > currentMinTime && currentTime < currentMaxTime)
                    }
                    return false
                },
                // 選中項(xiàng)
                onPick({ maxDate, minDate }) {
                    // console.log(maxDate)
                    currentFirstDate = !maxDate ? minDate : null
                }
            }
        }
    },
    watch: {
        // 處理手動(dòng)輸入的情況
        value: {
            handler(newVal, oldVal) {
                if (Array.isArray(newVal) && newVal.length === 2) {
                    if (this.compareHalfMonthInterval(newVal[0], newVal[1])) {
                        this.$message.warning('日期間隔不能超過(guò)半個(gè)月')
                        // 重置為oldVal或null
                        this.$emit('input', oldVal || null)
                    }
                }
            },
            immediate: true
        }
    },
    methods: {
        /**
         * 比較時(shí)間是否超出半個(gè)月
         * @param {*} startDate 開(kāi)始時(shí)間
         * @param {*} endDate 結(jié)束時(shí)間
         * @returns { boolean } true為超出半個(gè)月
         */
        compareHalfMonthInterval(startDate, endDate) {
            if (!startDate || !endDate) {
                return false
            }
            const startTime = new Date(startDate).getTime()
            const endTime = new Date(endDate).getTime()
            return (endTime - startTime) > 3600 * 1000 * 24 * 15
        }
    }
}
</script>

 到此這篇關(guān)于el-date-picker日期范圍限制的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)el-date-picker日期范圍限制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue.js實(shí)現(xiàn)圖片切換功能

    Vue.js實(shí)現(xiàn)圖片切換功能

    這篇文章主要為大家詳細(xì)介紹了Vue.js實(shí)現(xiàn)圖片切換功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Vue條件循環(huán)判斷+計(jì)算屬性+綁定樣式v-bind的實(shí)例

    Vue條件循環(huán)判斷+計(jì)算屬性+綁定樣式v-bind的實(shí)例

    今天小編就為大家分享一篇Vue條件循環(huán)判斷+計(jì)算屬性+綁定樣式v-bind的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • Vue之常用的內(nèi)置指令詳解

    Vue之常用的內(nèi)置指令詳解

    這篇文章主要為大家介紹了Vue之常用的內(nèi)置指令,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-11-11
  • Element中select多數(shù)據(jù)加載優(yōu)化的實(shí)現(xiàn)

    Element中select多數(shù)據(jù)加載優(yōu)化的實(shí)現(xiàn)

    本文主要介紹了Element中select多數(shù)據(jù)加載優(yōu)化的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 關(guān)于vue中ref的使用(this.$refs獲取為undefined)

    關(guān)于vue中ref的使用(this.$refs獲取為undefined)

    這篇文章主要介紹了關(guān)于vue中ref的使用(this.$refs獲取為undefined),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Vue 加載遠(yuǎn)程組件的解決方案

    Vue 加載遠(yuǎn)程組件的解決方案

    最近的項(xiàng)目有一個(gè)加載遠(yuǎn)程組件的需求,基于此我對(duì) Vue 加載遠(yuǎn)程組件的方案進(jìn)行了研究,并且整理了兩個(gè)可行的解決方案,有感興趣的小伙伴跟著小編一起來(lái)看看吧
    2023-07-07
  • Vue中iframe?結(jié)合?window.postMessage?實(shí)現(xiàn)跨域通信

    Vue中iframe?結(jié)合?window.postMessage?實(shí)現(xiàn)跨域通信

    window.postMessage()?方法可以安全地實(shí)現(xiàn)跨源通信,在一個(gè)項(xiàng)目的頁(yè)面中嵌入另一個(gè)項(xiàng)目的頁(yè)面,需要實(shí)現(xiàn)父子,子父頁(yè)面的通信,對(duì)Vue中iframe?結(jié)合?window.postMessage?實(shí)現(xiàn)跨域通信相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • vue輸入框使用模糊搜索功能的實(shí)現(xiàn)代碼

    vue輸入框使用模糊搜索功能的實(shí)現(xiàn)代碼

    這篇文章主要介紹了vue輸入框使用模糊搜索功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • vue導(dǎo)出html、word和pdf的實(shí)現(xiàn)代碼

    vue導(dǎo)出html、word和pdf的實(shí)現(xiàn)代碼

    這篇文章主要介紹了vue導(dǎo)出html、word和pdf的實(shí)現(xiàn)方法,文中完成了三種文件的導(dǎo)出但是還有很多種方法,小編就不給大家一一列舉了,需要的朋友可以參考下
    2018-07-07
  • Vue.js實(shí)現(xiàn)一個(gè)todo-list的上移下移刪除功能

    Vue.js實(shí)現(xiàn)一個(gè)todo-list的上移下移刪除功能

    這篇文章主要介紹了Vue.js實(shí)現(xiàn)一個(gè)todo-list的上移下移刪除功能,需要的朋友可以參考下
    2017-06-06

最新評(píng)論