<template> 
 | 
    <view class="uni-datetime-picker"> 
 | 
        <view @click="initTimePicker"> 
 | 
            <slot> 
 | 
                <view class="uni-datetime-picker-timebox-pointer" 
 | 
                    :class="{'uni-datetime-picker-disabled': disabled, 'uni-datetime-picker-timebox': border}"> 
 | 
                    <text class="uni-datetime-picker-text">{{time}}</text> 
 | 
                    <view v-if="!time" class="uni-datetime-picker-time"> 
 | 
                        <text class="uni-datetime-picker-text">{{selectTimeText}}</text> 
 | 
                    </view> 
 | 
                </view> 
 | 
            </slot> 
 | 
        </view> 
 | 
        <view v-if="visible" id="mask" class="uni-datetime-picker-mask" @click="tiggerTimePicker"></view> 
 | 
        <view v-if="visible" class="uni-datetime-picker-popup" :class="[dateShow && timeShow ? '' : 'fix-nvue-height']" 
 | 
            :style="fixNvueBug"> 
 | 
            <view class="uni-title"> 
 | 
                <text class="uni-datetime-picker-text">{{selectTimeText}}</text> 
 | 
            </view> 
 | 
            <view v-if="dateShow" class="uni-datetime-picker__container-box"> 
 | 
                <picker-view class="uni-datetime-picker-view" :indicator-style="indicatorStyle" :value="ymd" 
 | 
                    @change="bindDateChange"> 
 | 
                    <picker-view-column> 
 | 
                        <view class="uni-datetime-picker-item" v-for="(item,index) in years" :key="index"> 
 | 
                            <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> 
 | 
                        </view> 
 | 
                    </picker-view-column> 
 | 
                    <picker-view-column> 
 | 
                        <view class="uni-datetime-picker-item" v-for="(item,index) in months" :key="index"> 
 | 
                            <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> 
 | 
                        </view> 
 | 
                    </picker-view-column> 
 | 
                    <picker-view-column> 
 | 
                        <view class="uni-datetime-picker-item" v-for="(item,index) in days" :key="index"> 
 | 
                            <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> 
 | 
                        </view> 
 | 
                    </picker-view-column> 
 | 
                </picker-view> 
 | 
                <!-- 兼容 nvue 不支持伪类 --> 
 | 
                <text class="uni-datetime-picker-sign sign-left">-</text> 
 | 
                <text class="uni-datetime-picker-sign sign-right">-</text> 
 | 
            </view> 
 | 
            <view v-if="timeShow" class="uni-datetime-picker__container-box"> 
 | 
                <picker-view class="uni-datetime-picker-view" :class="[hideSecond ? 'time-hide-second' : '']" 
 | 
                    :indicator-style="indicatorStyle" :value="hms" @change="bindTimeChange"> 
 | 
                    <picker-view-column> 
 | 
                        <view class="uni-datetime-picker-item" v-for="(item,index) in hours" :key="index"> 
 | 
                            <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> 
 | 
                        </view> 
 | 
                    </picker-view-column> 
 | 
                    <picker-view-column> 
 | 
                        <view class="uni-datetime-picker-item" v-for="(item,index) in minutes" :key="index"> 
 | 
                            <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> 
 | 
                        </view> 
 | 
                    </picker-view-column> 
 | 
                    <picker-view-column v-if="!hideSecond"> 
 | 
                        <view class="uni-datetime-picker-item" v-for="(item,index) in seconds" :key="index"> 
 | 
                            <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> 
 | 
                        </view> 
 | 
                    </picker-view-column> 
 | 
                </picker-view> 
 | 
                <!-- 兼容 nvue 不支持伪类 --> 
 | 
                <text class="uni-datetime-picker-sign" :class="[hideSecond ? 'sign-center' : 'sign-left']">:</text> 
 | 
                <text v-if="!hideSecond" class="uni-datetime-picker-sign sign-right">:</text> 
 | 
            </view> 
 | 
            <view class="uni-datetime-picker-btn"> 
 | 
                <view @click="clearTime"> 
 | 
                    <text class="uni-datetime-picker-btn-text">{{clearText}}</text> 
 | 
                </view> 
 | 
                <view class="uni-datetime-picker-btn-group"> 
 | 
                    <view class="uni-datetime-picker-cancel" @click="tiggerTimePicker"> 
 | 
                        <text class="uni-datetime-picker-btn-text">{{cancelText}}</text> 
 | 
                    </view> 
 | 
                    <view @click="setTime"> 
 | 
                        <text class="uni-datetime-picker-btn-text">{{okText}}</text> 
 | 
                    </view> 
 | 
                </view> 
 | 
            </view> 
 | 
        </view> 
 | 
        <!-- #ifdef H5 --> 
 | 
        <!-- <keypress v-if="visible" @esc="tiggerTimePicker" @enter="setTime" /> --> 
 | 
        <!-- #endif --> 
 | 
    </view> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
    // #ifdef H5 
 | 
    import keypress from './keypress' 
 | 
    // #endif 
 | 
    import { 
 | 
        initVueI18n 
 | 
    } from '@dcloudio/uni-i18n' 
 | 
    import messages from './i18n/index.js' 
 | 
    const {    t    } = initVueI18n(messages) 
 | 
  
 | 
    /** 
 | 
     * DatetimePicker 时间选择器 
 | 
     * @description 可以同时选择日期和时间的选择器 
 | 
     * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx 
 | 
     * @property {String} type = [datetime | date | time] 显示模式 
 | 
     * @property {Boolean} multiple = [true|false] 是否多选 
 | 
     * @property {String|Number} value 默认值 
 | 
     * @property {String|Number} start 起始日期或时间 
 | 
     * @property {String|Number} end 起始日期或时间 
 | 
     * @property {String} return-type = [timestamp | string] 
 | 
     * @event {Function} change  选中发生变化触发 
 | 
     */ 
 | 
  
 | 
    export default { 
 | 
        name: 'UniDatetimePicker', 
 | 
        components: { 
 | 
            // #ifdef H5 
 | 
            keypress 
 | 
            // #endif 
 | 
        }, 
 | 
        data() { 
 | 
            return { 
 | 
                indicatorStyle: `height: 50px;`, 
 | 
                visible: false, 
 | 
                fixNvueBug: {}, 
 | 
                dateShow: true, 
 | 
                timeShow: true, 
 | 
                title: '日期和时间', 
 | 
                // 输入框当前时间 
 | 
                time: '', 
 | 
                // 当前的年月日时分秒 
 | 
                year: 1920, 
 | 
                month: 0, 
 | 
                day: 0, 
 | 
                hour: 0, 
 | 
                minute: 0, 
 | 
                second: 0, 
 | 
                // 起始时间 
 | 
                startYear: 1920, 
 | 
                startMonth: 1, 
 | 
                startDay: 1, 
 | 
                startHour: 0, 
 | 
                startMinute: 0, 
 | 
                startSecond: 0, 
 | 
                // 结束时间 
 | 
                endYear: 2120, 
 | 
                endMonth: 12, 
 | 
                endDay: 31, 
 | 
                endHour: 23, 
 | 
                endMinute: 59, 
 | 
                endSecond: 59, 
 | 
            } 
 | 
        }, 
 | 
        props: { 
 | 
            type: { 
 | 
                type: String, 
 | 
                default: 'datetime' 
 | 
            }, 
 | 
            value: { 
 | 
                type: [String, Number], 
 | 
                default: '' 
 | 
            }, 
 | 
            modelValue: { 
 | 
                type: [String, Number], 
 | 
                default: '' 
 | 
            }, 
 | 
            start: { 
 | 
                type: [Number, String], 
 | 
                default: '' 
 | 
            }, 
 | 
            end: { 
 | 
                type: [Number, String], 
 | 
                default: '' 
 | 
            }, 
 | 
            returnType: { 
 | 
                type: String, 
 | 
                default: 'string' 
 | 
            }, 
 | 
            disabled: { 
 | 
                type: [Boolean, String], 
 | 
                default: false 
 | 
            }, 
 | 
            border: { 
 | 
                type: [Boolean, String], 
 | 
                default: true 
 | 
            }, 
 | 
            hideSecond: { 
 | 
                type: [Boolean, String], 
 | 
                default: false 
 | 
            } 
 | 
        }, 
 | 
        watch: { 
 | 
            // #ifndef VUE3 
 | 
            value: { 
 | 
                handler(newVal, oldVal) { 
 | 
                    if (newVal) { 
 | 
                        this.parseValue(this.fixIosDateFormat(newVal)) //兼容 iOS、safari 日期格式 
 | 
                        this.initTime(false) 
 | 
                    } else { 
 | 
                        this.time = '' 
 | 
                        this.parseValue(Date.now()) 
 | 
                    } 
 | 
                }, 
 | 
                immediate: true 
 | 
            }, 
 | 
            // #endif 
 | 
            // #ifdef VUE3 
 | 
            modelValue: { 
 | 
                handler(newVal, oldVal) { 
 | 
                    if (newVal) { 
 | 
                        this.parseValue(this.fixIosDateFormat(newVal)) //兼容 iOS、safari 日期格式 
 | 
                        this.initTime(false) 
 | 
                    } else { 
 | 
                        this.time = '' 
 | 
                        this.parseValue(Date.now()) 
 | 
                    } 
 | 
                }, 
 | 
                immediate: true 
 | 
            }, 
 | 
            // #endif 
 | 
            type: { 
 | 
                handler(newValue) { 
 | 
                    if (newValue === 'date') { 
 | 
                        this.dateShow = true 
 | 
                        this.timeShow = false 
 | 
                        this.title = '日期' 
 | 
                    } else if (newValue === 'time') { 
 | 
                        this.dateShow = false 
 | 
                        this.timeShow = true 
 | 
                        this.title = '时间' 
 | 
                    } else { 
 | 
                        this.dateShow = true 
 | 
                        this.timeShow = true 
 | 
                        this.title = '日期和时间' 
 | 
                    } 
 | 
                }, 
 | 
                immediate: true 
 | 
            }, 
 | 
            start: { 
 | 
                handler(newVal) { 
 | 
                    this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'start') //兼容 iOS、safari 日期格式 
 | 
                }, 
 | 
                immediate: true 
 | 
            }, 
 | 
            end: { 
 | 
                handler(newVal) { 
 | 
                    this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'end') //兼容 iOS、safari 日期格式 
 | 
                }, 
 | 
                immediate: true 
 | 
            }, 
 | 
  
 | 
            // 月、日、时、分、秒可选范围变化后,检查当前值是否在范围内,不在则当前值重置为可选范围第一项 
 | 
            months(newVal) { 
 | 
                this.checkValue('month', this.month, newVal) 
 | 
            }, 
 | 
            days(newVal) { 
 | 
                this.checkValue('day', this.day, newVal) 
 | 
            }, 
 | 
            hours(newVal) { 
 | 
                this.checkValue('hour', this.hour, newVal) 
 | 
            }, 
 | 
            minutes(newVal) { 
 | 
                this.checkValue('minute', this.minute, newVal) 
 | 
            }, 
 | 
            seconds(newVal) { 
 | 
                this.checkValue('second', this.second, newVal) 
 | 
            } 
 | 
        }, 
 | 
        computed: { 
 | 
            // 当前年、月、日、时、分、秒选择范围 
 | 
            years() { 
 | 
                return this.getCurrentRange('year') 
 | 
            }, 
 | 
  
 | 
            months() { 
 | 
                return this.getCurrentRange('month') 
 | 
            }, 
 | 
  
 | 
            days() { 
 | 
                return this.getCurrentRange('day') 
 | 
            }, 
 | 
  
 | 
            hours() { 
 | 
                return this.getCurrentRange('hour') 
 | 
            }, 
 | 
  
 | 
            minutes() { 
 | 
                return this.getCurrentRange('minute') 
 | 
            }, 
 | 
  
 | 
            seconds() { 
 | 
                return this.getCurrentRange('second') 
 | 
            }, 
 | 
  
 | 
            // picker 当前值数组 
 | 
            ymd() { 
 | 
                return [this.year - this.minYear, this.month - this.minMonth, this.day - this.minDay] 
 | 
            }, 
 | 
            hms() { 
 | 
                return [this.hour - this.minHour, this.minute - this.minMinute, this.second - this.minSecond] 
 | 
            }, 
 | 
  
 | 
            // 当前 date 是 start 
 | 
            currentDateIsStart() { 
 | 
                return this.year === this.startYear && this.month === this.startMonth && this.day === this.startDay 
 | 
            }, 
 | 
  
 | 
            // 当前 date 是 end 
 | 
            currentDateIsEnd() { 
 | 
                return this.year === this.endYear && this.month === this.endMonth && this.day === this.endDay 
 | 
            }, 
 | 
  
 | 
            // 当前年、月、日、时、分、秒的最小值和最大值 
 | 
            minYear() { 
 | 
                return this.startYear 
 | 
            }, 
 | 
            maxYear() { 
 | 
                return this.endYear 
 | 
            }, 
 | 
            minMonth() { 
 | 
                if (this.year === this.startYear) { 
 | 
                    return this.startMonth 
 | 
                } else { 
 | 
                    return 1 
 | 
                } 
 | 
            }, 
 | 
            maxMonth() { 
 | 
                if (this.year === this.endYear) { 
 | 
                    return this.endMonth 
 | 
                } else { 
 | 
                    return 12 
 | 
                } 
 | 
            }, 
 | 
            minDay() { 
 | 
                if (this.year === this.startYear && this.month === this.startMonth) { 
 | 
                    return this.startDay 
 | 
                } else { 
 | 
                    return 1 
 | 
                } 
 | 
            }, 
 | 
            maxDay() { 
 | 
                if (this.year === this.endYear && this.month === this.endMonth) { 
 | 
                    return this.endDay 
 | 
                } else { 
 | 
                    return this.daysInMonth(this.year, this.month) 
 | 
                } 
 | 
            }, 
 | 
            minHour() { 
 | 
                if (this.type === 'datetime') { 
 | 
                    if (this.currentDateIsStart) { 
 | 
                        return this.startHour 
 | 
                    } else { 
 | 
                        return 0 
 | 
                    } 
 | 
                } 
 | 
                if (this.type === 'time') { 
 | 
                    return this.startHour 
 | 
                } 
 | 
            }, 
 | 
            maxHour() { 
 | 
                if (this.type === 'datetime') { 
 | 
                    if (this.currentDateIsEnd) { 
 | 
                        return this.endHour 
 | 
                    } else { 
 | 
                        return 23 
 | 
                    } 
 | 
                } 
 | 
                if (this.type === 'time') { 
 | 
                    return this.endHour 
 | 
                } 
 | 
            }, 
 | 
            minMinute() { 
 | 
                if (this.type === 'datetime') { 
 | 
                    if (this.currentDateIsStart && this.hour === this.startHour) { 
 | 
                        return this.startMinute 
 | 
                    } else { 
 | 
                        return 0 
 | 
                    } 
 | 
                } 
 | 
                if (this.type === 'time') { 
 | 
                    if (this.hour === this.startHour) { 
 | 
                        return this.startMinute 
 | 
                    } else { 
 | 
                        return 0 
 | 
                    } 
 | 
                } 
 | 
            }, 
 | 
            maxMinute() { 
 | 
                if (this.type === 'datetime') { 
 | 
                    if (this.currentDateIsEnd && this.hour === this.endHour) { 
 | 
                        return this.endMinute 
 | 
                    } else { 
 | 
                        return 59 
 | 
                    } 
 | 
                } 
 | 
                if (this.type === 'time') { 
 | 
                    if (this.hour === this.endHour) { 
 | 
                        return this.endMinute 
 | 
                    } else { 
 | 
                        return 59 
 | 
                    } 
 | 
                } 
 | 
            }, 
 | 
            minSecond() { 
 | 
                if (this.type === 'datetime') { 
 | 
                    if (this.currentDateIsStart && this.hour === this.startHour && this.minute === this.startMinute) { 
 | 
                        return this.startSecond 
 | 
                    } else { 
 | 
                        return 0 
 | 
                    } 
 | 
                } 
 | 
                if (this.type === 'time') { 
 | 
                    if (this.hour === this.startHour && this.minute === this.startMinute) { 
 | 
                        return this.startSecond 
 | 
                    } else { 
 | 
                        return 0 
 | 
                    } 
 | 
                } 
 | 
            }, 
 | 
            maxSecond() { 
 | 
                if (this.type === 'datetime') { 
 | 
                    if (this.currentDateIsEnd && this.hour === this.endHour && this.minute === this.endMinute) { 
 | 
                        return this.endSecond 
 | 
                    } else { 
 | 
                        return 59 
 | 
                    } 
 | 
                } 
 | 
                if (this.type === 'time') { 
 | 
                    if (this.hour === this.endHour && this.minute === this.endMinute) { 
 | 
                        return this.endSecond 
 | 
                    } else { 
 | 
                        return 59 
 | 
                    } 
 | 
                } 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * for i18n 
 | 
             */ 
 | 
            selectTimeText() { 
 | 
                return t("uni-datetime-picker.selectTime") 
 | 
            }, 
 | 
            okText() { 
 | 
                return t("uni-datetime-picker.ok") 
 | 
            }, 
 | 
            clearText() { 
 | 
                return t("uni-datetime-picker.clear") 
 | 
            }, 
 | 
            cancelText() { 
 | 
                return t("uni-datetime-picker.cancel") 
 | 
            } 
 | 
        }, 
 | 
  
 | 
        mounted() { 
 | 
            // #ifdef APP-NVUE 
 | 
            const res = uni.getSystemInfoSync(); 
 | 
            this.fixNvueBug = { 
 | 
                top: res.windowHeight / 2, 
 | 
                left: res.windowWidth / 2 
 | 
            } 
 | 
            // #endif 
 | 
        }, 
 | 
  
 | 
        methods: { 
 | 
            /** 
 | 
             * @param {Object} item 
 | 
             * 小于 10 在前面加个 0 
 | 
             */ 
 | 
  
 | 
            lessThanTen(item) { 
 | 
                return item < 10 ? '0' + item : item 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 解析时分秒字符串,例如:00:00:00 
 | 
             * @param {String} timeString 
 | 
             */ 
 | 
            parseTimeType(timeString) { 
 | 
                if (timeString) { 
 | 
                    let timeArr = timeString.split(':') 
 | 
                    this.hour = Number(timeArr[0]) 
 | 
                    this.minute = Number(timeArr[1]) 
 | 
                    this.second = Number(timeArr[2]) 
 | 
                } 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 解析选择器初始值,类型可以是字符串、时间戳,例如:2000-10-02、'08:30:00'、 1610695109000 
 | 
             * @param {String | Number} datetime 
 | 
             */ 
 | 
            initPickerValue(datetime) { 
 | 
                let defaultValue = null 
 | 
                if (datetime) { 
 | 
                    defaultValue = this.compareValueWithStartAndEnd(datetime, this.start, this.end) 
 | 
                } else { 
 | 
                    defaultValue = Date.now() 
 | 
                    defaultValue = this.compareValueWithStartAndEnd(defaultValue, this.start, this.end) 
 | 
                } 
 | 
                this.parseValue(defaultValue) 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 初始值规则: 
 | 
             * - 用户设置初始值 value 
 | 
             *     - 设置了起始时间 start、终止时间 end,并 start < value < end,初始值为 value, 否则初始值为 start 
 | 
             *     - 只设置了起始时间 start,并 start < value,初始值为 value,否则初始值为 start 
 | 
             *     - 只设置了终止时间 end,并 value < end,初始值为 value,否则初始值为 end 
 | 
             *     - 无起始终止时间,则初始值为 value 
 | 
             * - 无初始值 value,则初始值为当前本地时间 Date.now() 
 | 
             * @param {Object} value 
 | 
             * @param {Object} dateBase 
 | 
             */ 
 | 
            compareValueWithStartAndEnd(value, start, end) { 
 | 
                let winner = null 
 | 
                value = this.superTimeStamp(value) 
 | 
                start = this.superTimeStamp(start) 
 | 
                end = this.superTimeStamp(end) 
 | 
  
 | 
                if (start && end) { 
 | 
                    if (value < start) { 
 | 
                        winner = new Date(start) 
 | 
                    } else if (value > end) { 
 | 
                        winner = new Date(end) 
 | 
                    } else { 
 | 
                        winner = new Date(value) 
 | 
                    } 
 | 
                } else if (start && !end) { 
 | 
                    winner = start <= value ? new Date(value) : new Date(start) 
 | 
                } else if (!start && end) { 
 | 
                    winner = value <= end ? new Date(value) : new Date(end) 
 | 
                } else { 
 | 
                    winner = new Date(value) 
 | 
                } 
 | 
  
 | 
                return winner 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 转换为可比较的时间戳,接受日期、时分秒、时间戳 
 | 
             * @param {Object} value 
 | 
             */ 
 | 
            superTimeStamp(value) { 
 | 
                let dateBase = '' 
 | 
                if (this.type === 'time' && value && typeof value === 'string') { 
 | 
                    const now = new Date() 
 | 
                    const year = now.getFullYear() 
 | 
                    const month = now.getMonth() + 1 
 | 
                    const day = now.getDate() 
 | 
                    dateBase = year + '/' + month + '/' + day + ' ' 
 | 
                } 
 | 
                if (Number(value) && typeof value !== NaN) { 
 | 
                    value = parseInt(value) 
 | 
                    dateBase = 0 
 | 
                } 
 | 
                return this.createTimeStamp(dateBase + value) 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 解析默认值 value,字符串、时间戳 
 | 
             * @param {Object} defaultTime 
 | 
             */ 
 | 
            parseValue(value) { 
 | 
                if (!value) { 
 | 
                    return 
 | 
                } 
 | 
                if (this.type === 'time' && typeof value === "string") { 
 | 
                    this.parseTimeType(value) 
 | 
                } else { 
 | 
                    let defaultDate = null 
 | 
                    defaultDate = new Date(value) 
 | 
                    if (this.type !== 'time') { 
 | 
                        this.year = defaultDate.getFullYear() 
 | 
                        this.month = defaultDate.getMonth() + 1 
 | 
                        this.day = defaultDate.getDate() 
 | 
                    } 
 | 
                    if (this.type !== 'date') { 
 | 
                        this.hour = defaultDate.getHours() 
 | 
                        this.minute = defaultDate.getMinutes() 
 | 
                        this.second = defaultDate.getSeconds() 
 | 
                    } 
 | 
                } 
 | 
                if (this.hideSecond) { 
 | 
                    this.second = 0 
 | 
                } 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 解析可选择时间范围 start、end,年月日字符串、时间戳 
 | 
             * @param {Object} defaultTime 
 | 
             */ 
 | 
            parseDatetimeRange(point, pointType) { 
 | 
                // 时间为空,则重置为初始值 
 | 
                if (!point) { 
 | 
                    if (pointType === 'start') { 
 | 
                        this.startYear = 1920 
 | 
                        this.startMonth = 1 
 | 
                        this.startDay = 1 
 | 
                        this.startHour = 0 
 | 
                        this.startMinute = 0 
 | 
                        this.startSecond = 0 
 | 
                    } 
 | 
                    if (pointType === 'end') { 
 | 
                        this.endYear = 2120 
 | 
                        this.endMonth = 12 
 | 
                        this.endDay = 31 
 | 
                        this.endHour = 23 
 | 
                        this.endMinute = 59 
 | 
                        this.endSecond = 59 
 | 
                    } 
 | 
                    return 
 | 
                } 
 | 
                if (this.type === 'time') { 
 | 
                    const pointArr = point.split(':') 
 | 
                    this[pointType + 'Hour'] = Number(pointArr[0]) 
 | 
                    this[pointType + 'Minute'] = Number(pointArr[1]) 
 | 
                    this[pointType + 'Second'] = Number(pointArr[2]) 
 | 
                } else { 
 | 
                    if (!point) { 
 | 
                        pointType === 'start' ? this.startYear = this.year - 60 : this.endYear = this.year + 60 
 | 
                        return 
 | 
                    } 
 | 
                    if (Number(point) && Number(point) !== NaN) { 
 | 
                        point = parseInt(point) 
 | 
                    } 
 | 
                    // datetime 的 end 没有时分秒, 则不限制 
 | 
                    const hasTime = /[0-9]:[0-9]/ 
 | 
                    if (this.type === 'datetime' && pointType === 'end' && typeof point === 'string' && !hasTime.test( 
 | 
                            point)) { 
 | 
                        point = point + ' 23:59:59' 
 | 
                    } 
 | 
                    const pointDate = new Date(point) 
 | 
                    this[pointType + 'Year'] = pointDate.getFullYear() 
 | 
                    this[pointType + 'Month'] = pointDate.getMonth() + 1 
 | 
                    this[pointType + 'Day'] = pointDate.getDate() 
 | 
                    if (this.type === 'datetime') { 
 | 
                        this[pointType + 'Hour'] = pointDate.getHours() 
 | 
                        this[pointType + 'Minute'] = pointDate.getMinutes() 
 | 
                        this[pointType + 'Second'] = pointDate.getSeconds() 
 | 
                    } 
 | 
                } 
 | 
            }, 
 | 
  
 | 
            // 获取 年、月、日、时、分、秒 当前可选范围 
 | 
            getCurrentRange(value) { 
 | 
                const range = [] 
 | 
                for (let i = this['min' + this.capitalize(value)]; i <= this['max' + this.capitalize(value)]; i++) { 
 | 
                    range.push(i) 
 | 
                } 
 | 
                return range 
 | 
            }, 
 | 
  
 | 
            // 字符串首字母大写 
 | 
            capitalize(str) { 
 | 
                return str.charAt(0).toUpperCase() + str.slice(1) 
 | 
            }, 
 | 
  
 | 
            // 检查当前值是否在范围内,不在则当前值重置为可选范围第一项 
 | 
            checkValue(name, value, values) { 
 | 
                if (values.indexOf(value) === -1) { 
 | 
                    this[name] = values[0] 
 | 
                } 
 | 
            }, 
 | 
  
 | 
            // 每个月的实际天数 
 | 
            daysInMonth(year, month) { // Use 1 for January, 2 for February, etc. 
 | 
                return new Date(year, month, 0).getDate(); 
 | 
            }, 
 | 
  
 | 
            //兼容 iOS、safari 日期格式 
 | 
            fixIosDateFormat(value) { 
 | 
                if (typeof value === 'string') { 
 | 
                    value = value.replace(/-/g, '/') 
 | 
                } 
 | 
                return value 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 生成时间戳 
 | 
             * @param {Object} time 
 | 
             */ 
 | 
            createTimeStamp(time) { 
 | 
                if (!time) return 
 | 
                if (typeof time === "number") { 
 | 
                    return time 
 | 
                } else { 
 | 
                    time = time.replace(/-/g, '/') 
 | 
                    if (this.type === 'date') { 
 | 
                        time = time + ' ' + '00:00:00' 
 | 
                    } 
 | 
                    return Date.parse(time) 
 | 
                } 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 生成日期或时间的字符串 
 | 
             */ 
 | 
            createDomSting() { 
 | 
                const yymmdd = this.year + 
 | 
                    '-' + 
 | 
                    this.lessThanTen(this.month) + 
 | 
                    '-' + 
 | 
                    this.lessThanTen(this.day) 
 | 
  
 | 
                let hhmmss = this.lessThanTen(this.hour) + 
 | 
                    ':' + 
 | 
                    this.lessThanTen(this.minute) 
 | 
  
 | 
                if (!this.hideSecond) { 
 | 
                    hhmmss = hhmmss + ':' + this.lessThanTen(this.second) 
 | 
                } 
 | 
  
 | 
                if (this.type === 'date') { 
 | 
                    return yymmdd 
 | 
                } else if (this.type === 'time') { 
 | 
                    return hhmmss 
 | 
                } else { 
 | 
                    return yymmdd + ' ' + hhmmss 
 | 
                } 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 初始化返回值,并抛出 change 事件 
 | 
             */ 
 | 
            initTime(emit = true) { 
 | 
                this.time = this.createDomSting() 
 | 
                if (!emit) return 
 | 
                if (this.returnType === 'timestamp' && this.type !== 'time') { 
 | 
                    this.$emit('change', this.createTimeStamp(this.time)) 
 | 
                    this.$emit('input', this.createTimeStamp(this.time)) 
 | 
                    this.$emit('update:modelValue', this.createTimeStamp(this.time)) 
 | 
                } else { 
 | 
                    this.$emit('change', this.time) 
 | 
                    this.$emit('input', this.time) 
 | 
                    this.$emit('update:modelValue', this.time) 
 | 
                } 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 用户选择日期或时间更新 data 
 | 
             * @param {Object} e 
 | 
             */ 
 | 
            bindDateChange(e) { 
 | 
                const val = e.detail.value 
 | 
                this.year = this.years[val[0]] 
 | 
                this.month = this.months[val[1]] 
 | 
                this.day = this.days[val[2]] 
 | 
            }, 
 | 
            bindTimeChange(e) { 
 | 
                const val = e.detail.value 
 | 
                this.hour = this.hours[val[0]] 
 | 
                this.minute = this.minutes[val[1]] 
 | 
                this.second = this.seconds[val[2]] 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 初始化弹出层 
 | 
             */ 
 | 
            initTimePicker() { 
 | 
                if (this.disabled) return 
 | 
                const value = this.fixIosDateFormat(this.value) 
 | 
                this.initPickerValue(value) 
 | 
                this.visible = !this.visible 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 触发或关闭弹框 
 | 
             */ 
 | 
            tiggerTimePicker(e) { 
 | 
                this.visible = !this.visible 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 用户点击“清空”按钮,清空当前值 
 | 
             */ 
 | 
            clearTime() { 
 | 
                this.time = '' 
 | 
                this.$emit('change', this.time) 
 | 
                this.$emit('input', this.time) 
 | 
                this.$emit('update:modelValue', this.time) 
 | 
                this.tiggerTimePicker() 
 | 
            }, 
 | 
  
 | 
            /** 
 | 
             * 用户点击“确定”按钮 
 | 
             */ 
 | 
            setTime() { 
 | 
                this.initTime() 
 | 
                this.tiggerTimePicker() 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
</script> 
 | 
  
 | 
<style lang="scss"> 
 | 
    $uni-primary: #007aff !default; 
 | 
  
 | 
    .uni-datetime-picker { 
 | 
        /* #ifndef APP-NVUE */ 
 | 
        /* width: 100%; */ 
 | 
        /* #endif */ 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-view { 
 | 
        height: 130px; 
 | 
        width: 270px; 
 | 
        /* #ifndef APP-NVUE */ 
 | 
        cursor: pointer; 
 | 
        /* #endif */ 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-item { 
 | 
        height: 50px; 
 | 
        line-height: 50px; 
 | 
        text-align: center; 
 | 
        font-size: 14px; 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-btn { 
 | 
        margin-top: 60px; 
 | 
        /* #ifndef APP-NVUE */ 
 | 
        display: flex; 
 | 
        cursor: pointer; 
 | 
        /* #endif */ 
 | 
        flex-direction: row; 
 | 
        justify-content: space-between; 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-btn-text { 
 | 
        font-size: 14px; 
 | 
        color: $uni-primary; 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-btn-group { 
 | 
        /* #ifndef APP-NVUE */ 
 | 
        display: flex; 
 | 
        /* #endif */ 
 | 
        flex-direction: row; 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-cancel { 
 | 
        margin-right: 30px; 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-mask { 
 | 
        position: fixed; 
 | 
        bottom: 0px; 
 | 
        top: 0px; 
 | 
        left: 0px; 
 | 
        right: 0px; 
 | 
        background-color: rgba(0, 0, 0, 0.4); 
 | 
        transition-duration: 0.3s; 
 | 
        z-index: 998; 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-popup { 
 | 
        border-radius: 8px; 
 | 
        padding: 30px; 
 | 
        width: 270px; 
 | 
        /* #ifdef APP-NVUE */ 
 | 
        height: 500px; 
 | 
        /* #endif */ 
 | 
        /* #ifdef APP-NVUE */ 
 | 
        width: 330px; 
 | 
        /* #endif */ 
 | 
        background-color: #fff; 
 | 
        position: fixed; 
 | 
        top: 50%; 
 | 
        left: 50%; 
 | 
        transform: translate(-50%, -50%); 
 | 
        transition-duration: 0.3s; 
 | 
        z-index: 999; 
 | 
    } 
 | 
  
 | 
    .fix-nvue-height { 
 | 
        /* #ifdef APP-NVUE */ 
 | 
        height: 330px; 
 | 
        /* #endif */ 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-time { 
 | 
        color: grey; 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-column { 
 | 
        height: 50px; 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-timebox { 
 | 
  
 | 
        border: 1px solid #E5E5E5; 
 | 
        border-radius: 5px; 
 | 
        padding: 7px 10px; 
 | 
        /* #ifndef APP-NVUE */ 
 | 
        box-sizing: border-box; 
 | 
        cursor: pointer; 
 | 
        /* #endif */ 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-timebox-pointer { 
 | 
        /* #ifndef APP-NVUE */ 
 | 
        cursor: pointer; 
 | 
        /* #endif */ 
 | 
    } 
 | 
  
 | 
  
 | 
    .uni-datetime-picker-disabled { 
 | 
        opacity: 0.4; 
 | 
        /* #ifdef H5 */ 
 | 
        cursor: not-allowed !important; 
 | 
        /* #endif */ 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-text { 
 | 
        font-size: 14px; 
 | 
        line-height: 50px 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker-sign { 
 | 
        position: absolute; 
 | 
        top: 53px; 
 | 
        /* 减掉 10px 的元素高度,兼容nvue */ 
 | 
        color: #999; 
 | 
        /* #ifdef APP-NVUE */ 
 | 
        font-size: 16px; 
 | 
        /* #endif */ 
 | 
    } 
 | 
  
 | 
    .sign-left { 
 | 
        left: 86px; 
 | 
    } 
 | 
  
 | 
    .sign-right { 
 | 
        right: 86px; 
 | 
    } 
 | 
  
 | 
    .sign-center { 
 | 
        left: 135px; 
 | 
    } 
 | 
  
 | 
    .uni-datetime-picker__container-box { 
 | 
        position: relative; 
 | 
        display: flex; 
 | 
        align-items: center; 
 | 
        justify-content: center; 
 | 
        margin-top: 40px; 
 | 
    } 
 | 
  
 | 
    .time-hide-second { 
 | 
        width: 180px; 
 | 
    } 
 | 
</style> 
 |