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

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

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

前言

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

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

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

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

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

聲明了全局組件HalfMonthPicker

組件模板定義

組件中使用v-bind="attrs"和v−on="attrs"和v-on="attrs"和v−on="listeners"進(jìn)行了屬性和事件透傳,方便后期維護(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)屬性值

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

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

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

基本變量定義

currentFirstDate

首個選中的日期

currentFirstTime

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

currentMinTime

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

currentMaxTime

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

currentTime

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

shortcuts快捷選項(xiàng)

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

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

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

如果不存在,則皆可選。

onPick注意事項(xiàng)

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

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

2.minDate存在,而maxDate不存在

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

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

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

未置為null

微信截圖_20230504171113.png

置為null 

微信截圖_20230504171129.png

computed: {
    pickerOptions() {
        const { value } = this
        // 選中的首個日期
        let currentFirstDate = Array.isArray(value) && value.length === 1 && value[0] ? value[0] : null
        // 選中的首個日期毫秒數(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)用戶選擇在input框中手動輸入日期時(shí),pickerOptions中的disabledDate禁選屬性便無法對用戶產(chǎn)生攔截作用,此時(shí)便需要通過監(jiān)聽value屬性的變化,當(dāng)newVal間隔大于半個月時(shí),重置回oldVal。

微信截圖_20230504164206.png

watch: {
    // 處理手動輸入的情況
    value: {
        handler(newVal, oldVal) {
            if (Array.isArray(newVal) && newVal.length === 2) {
                if (this.compareHalfMonthInterval(newVal[0], newVal[1])) {
                    this.$message.warning('日期間隔不能超過半個月')
                    // 重置為oldVal或null
                    this.$emit('input', oldVal || null)
                }
            }
        },
        immediate: true
    }
},
methods: {
    /**
     * 比較時(shí)間是否超出半個月
     * @param {*} startDate 開始時(shí)間
     * @param {*} endDate 結(jié)束時(shí)間
     * @returns { boolean } true為超出半個月
     */
    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
    }
}

頁面中使用

使用前

微信截圖_20230504165349.png

微信截圖_20230504165518.png

使用后 

微信截圖_20230504165441.png

微信截圖_20230504165558.png

使用效果

選擇開始日期

微信截圖_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
            // 選中的首個日期
            let currentFirstDate = Array.isArray(value) && value.length === 1 && value[0] ? value[0] : null
            // 選中的首個日期毫秒數(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: {
        // 處理手動輸入的情況
        value: {
            handler(newVal, oldVal) {
                if (Array.isArray(newVal) && newVal.length === 2) {
                    if (this.compareHalfMonthInterval(newVal[0], newVal[1])) {
                        this.$message.warning('日期間隔不能超過半個月')
                        // 重置為oldVal或null
                        this.$emit('input', oldVal || null)
                    }
                }
            },
            immediate: true
        }
    },
    methods: {
        /**
         * 比較時(shí)間是否超出半個月
         * @param {*} startDate 開始時(shí)間
         * @param {*} endDate 結(jié)束時(shí)間
         * @returns { boolean } true為超出半個月
         */
        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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論