美文网首页前端开发那些事儿
【Vue3+Vite+TS】11.0 组件八:时间选择组件

【Vue3+Vite+TS】11.0 组件八:时间选择组件

作者: bobokaka | 来源:发表于2022-01-02 14:52 被阅读0次

    必备UI组件

    将用到的组件:
    TimeSelect 时间选择

    DatePicker 日期选择器

    时间选择

    新建src\components\baseline\chooseTime\src\index.vue

    <template>
        <div class="bs-wrapper">
            <div class="box">
                <!-- :max-time="endTime" -->
                <el-time-select
                    v-bind="$attrs.startOptions"
                    v-model="startTime"
                    :placeholder="startPlaceholder"
                    :start="startTimeStart"
                    :step="startStep"
                    :end="startTimeEnd"
                ></el-time-select>
            </div>
            <div class="box">
                <el-time-select
                    v-bind="$attrs.endOptions"
                    v-model="endTime"
                    :min-time="startTime"
                    :placeholder="endPlaceholder"
                    :start="endTimeStart"
                    :step="endStep"
                    :end="endTimeEnd"
                    :disabled="endTimeDisabled"
                ></el-time-select>
            </div>
        </div>
    </template>
    <script lang="ts" setup>
    import { ref, watch } from 'vue'
    
    const props = defineProps({
        //说明:开始时间提示
        startPlaceholder: {
            type: String,
            default: '请选择开始时间',
        },
        //说明:开始时间的默认开始选择
        startTimeStart: {
            type: String,
            default: '00:00',
        },
        // 说明:开始时间时间间隔
        startStep: {
            type: String,
            default: '00:30',
        },
        //说明:开始时间的默认结束选择
        startTimeEnd: {
            type: String,
            default: '24:00',
        },
    
        //说明:结束时间提示
        endPlaceholder: {
            type: String,
            default: '请选择结束时间',
        },
        //说明:结束时间的默认开始选择
        endTimeStart: {
            type: String,
            default: '00:00',
        },
        // 说明:结束时间时间间隔
        endStep: {
            type: String,
            default: '00:30',
        },
        //说明:结束时间的默认结束选择
        endTimeEnd: {
            type: String,
            default: '24:00',
        },
    })
    
    //子传父
    let emits = defineEmits(['startChange', 'endChange'])
    // 开始时间
    const startTime = ref<string>('')
    // 结束时间
    const endTime = ref<string>('')
    // 结束时间是否显示可编辑:默认不可编辑
    const endTimeDisabled = ref<boolean>(true)
    //开始时间清空,联动把结束时间也清空
    watch(
        () => startTime.value,
        val => {
            if (val === '') {
                endTime.value = ''
                endTimeDisabled.value = true
            } else {
                endTimeDisabled.value = false
                endTime.value = ''
                //给父组件分发事件
                emits('startChange', val)
            }
        }
    )
    //结束时间监听
    watch(
        () => endTime.value,
        val => {
            if (val !== '') {
                emits('endChange', {
                    startTime: startTime.value,
                    endTime: val,
                })
            }
        }
    )
    </script>
    
    <style lang="scss" scoped>
    .bs-wrapper {
        display: flex;
    }
    .box {
        margin-right: 0.2rem;
    }
    </style>
    
    

    新建src\components\baseline\chooseTime\index.ts

    import { App } from 'vue'
    import ChooseTime from './src/index.vue'
    
    export { ChooseTime }
    
    //组件可通过use的形式使用
    export default {
      ChooseTime,
        install(app: App) {
            app.component('bs-choose-time', ChooseTime)
        },
    }
    
    

    修改src\components\baseline\container\index.ts

    /*
     * @Author: bobokaka
     * @Date: 2021-12-20 01:41:54
     * @LastEditTime: 2022-01-01 23:07:26
     * @LastEditors: Please set LastEditors
     * @Description: 全局基础组件全局注册
     * @FilePath: \vue3-element-ui-baseline\src\components\baseline\index.ts
     */
    import { App } from 'vue'
    import ChooseArea from './chooseArea'
    import ChooseIcon from './chooseIcon'
    import Container from './container'
    import Trend from './trend'
    import Notification from './notification'
    import List from './list'
    import Menu from './menu'
    import Progress from './progress'
    import ChooseTime from './chooseTime'
    
    const components = [
        ChooseArea,
        ChooseIcon,
        Container,
        Trend,
        Notification,
        List,
        Menu,
        Progress,
        ChooseTime,
    ]
    export {
        ChooseArea,
        ChooseIcon,
        Container,
        Trend,
        Notification,
        List,
        Menu,
        Progress,
        ChooseTime,
    }
    
    //组件可通过use的形式使用
    export default {
        install(app: App) {
            components.map(item => {
                app.use(item)
            })
        },
        ChooseArea,
        ChooseIcon,
        Container,
        Trend,
        Notification,
        List,
        Menu,
        Progress,
        ChooseTime,
    }
    
    

    路由新增新的路由:

     {
                    path: '/chooseTime',
                    component: () =>
                        import('../views/baseline/chooseTime/index.vue'),
                },
    

    新增src\views\baseline\chooseTime\index.vue

    <template>
        <div>
            <bs-choose-time
                @startChange="startChange"
                @endChange="endChange"
            ></bs-choose-time>
            <br />
            <bs-choose-time
                :startOptions="startOptions"
                :endOptions="endOptions"
            ></bs-choose-time>
        </div>
    </template>
    <script lang="ts" setup>
    interface timeValue {
        startTime: string
        endTime: string
    }
    const startChange = (value: string) => {
        console.log('startChange', value)
    }
    const endChange = (value: timeValue) => {
        console.log('endChange', value)
    }
    
    const startOptions = { size: 'mini', clearable: false }
    
    const endOptions = { size: 'mini', clearable: false }
    </script>
    <style lang="scss" scoped></style>
    
    

    效果如下:


    image.png
    image.png

    日期选择

    新建src\components\baseline\chooseDate\src\index.vue

    <!--
     * @Author: bobokaka
     * @Date: 2021-12-23 00:07:25
     * @LastEditDate: 2022-01-02 12:17:03
     * @LastEditors: Please set LastEditors
     * @Description: 时间选择器
     * @FilePath: \vue3-element-ui-baseline\src\components\baseline\trend\src\index.vue
    -->
    <template>
        <div class="bs-wrapper">
            <div class="box__start">
                <!-- :max-time="endDate" -->
                <el-date-picker
                    v-model="stratDate"
                    v-bind="$attrs.startOptions"
                    type="date"
                    :placeholder="startPlaceholder"
                    :disabled-date="startDisabledDate"
                ></el-date-picker>
            </div>
            <div>
                <el-date-picker
                    v-model="endDate"
                    v-bind="$attrs.endOptions"
                    type="date"
                    :placeholder="endPlaceholder"
                    :disabled="endDateDisabled"
                    :disabled-date="endDisabledDate"
                ></el-date-picker>
            </div>
            <div></div>
        </div>
    </template>
    <script lang="ts" setup>
    import { ref, watch } from 'vue'
    
    const props = defineProps({
        //说明:开始日期提示
        startPlaceholder: {
            type: String,
            default: '请选择开始日期',
        },
        //说明:结束日期提示
        endPlaceholder: {
            type: String,
            default: '请选择结束日期',
        },
        //是否禁用选择今天之前的日期
        disableBeforeToDay: {
            type: Boolean,
            default: false,
        },
        //是否禁用选择今天之后的日期
        disableAfterToDay: {
            type: Boolean,
            default: false,
        },
        //可否选择当天
        selectToDay: {
            type: Boolean,
            default: true,
        },
    })
    
    //子传父
    let emits = defineEmits(['startChange', 'endChange'])
    //开始日期
    const stratDate = ref<Date | null>(null)
    
    //结束日期
    const endDate = ref<Date | null>(null)
    // 结束日期是否显示可编辑:默认不可编辑
    const endDateDisabled = ref<boolean>(true)
    
    //一天的毫秒数
    const oneDateNumber = 1000 * 60 * 60 * 24
    //禁用开始日期的函数
    let startDisabledDate = (time: Date) => {
        if (props.disableBeforeToDay && props.disableAfterToDay) {
            return (
                time.getTime() < Date.now() - oneDateNumber ||
                time.getTime() > Date.now() - oneDateNumber
            )
        } else if (props.disableBeforeToDay) {
            return time.getTime() < Date.now() - oneDateNumber
        } else if (props.disableAfterToDay) {
            return time.getTime() > Date.now() - oneDateNumber
        }
    }
    //禁用结束日期的函数
    const endDisabledDate = (time: Date) => {
        //是否禁用选择今天之前的日期\是否禁用选择今天之后的日期
        //此时无意义,结束日期不能选任何值
        if (props.disableBeforeToDay && props.disableAfterToDay) {
            if (stratDate.value) {
                return (
                    time.getTime() < Date.now() - oneDateNumber ||
                    time.getTime() > Date.now() - oneDateNumber ||
                    (props.selectToDay
                        ? time.getTime() <=
                          stratDate.value.getTime() - oneDateNumber
                        : time.getTime() <
                          stratDate.value.getTime() + oneDateNumber)
                )
            }
        } else if (props.disableBeforeToDay) {
            //假设开始时间是2022-04-1
            //禁用选择今天之前的日期,比如今天是2022-04-10
            //selectToDay 可否选择当天:true 可,可以选择包括开始日期到当天之前的日期,范围是2022-04-1至2022-04-10
            //selectToDay 可否选择当天:false 不可,可以选择包括开始日期下一天到当天之前的日期,范围是2022-04-2至2022-04-10
            if (stratDate.value) {
                return (
                    time.getTime() < Date.now() - oneDateNumber ||
                    (props.selectToDay
                        ? time.getTime() <=
                          stratDate.value.getTime() - oneDateNumber
                        : time.getTime() <
                          stratDate.value.getTime() + oneDateNumber)
                )
            }
        } else if (props.disableAfterToDay) {
            //假设开始时间是2022-04-15
            //禁用选择今天之后的日期,比如今天是2022-04-10
            //selectToDay 可否选择当天:true 可,可以选择开始日期、当天之后的日期,范围是2022-04-15之后的日期
            //selectToDay 可否选择当天:false 不可,可以选择开始日期、当天之后的日期,范围是2022-04-16之后的日期
            if (stratDate.value) {
                return (
                    time.getTime() > Date.now() - oneDateNumber ||
                    (props.selectToDay
                        ? time.getTime() <=
                          stratDate.value.getTime() - oneDateNumber
                        : time.getTime() <
                          stratDate.value.getTime() + oneDateNumber)
                )
            }
        } else {
            //假设开始时间是2022-04-15
            //比如今天是2022-04-10
            //selectToDay 可否选择当天:true 可,可以选择开始日期之后的日期,范围是2022-04-15之后的日期
            //selectToDay 可否选择当天:false 不可,可以选择开始日期之后的日期,范围是2022-04-16之后的日期
            if (stratDate.value) {
                return props.selectToDay
                    ? time.getTime() <= stratDate.value.getTime() - oneDateNumber
                    : time.getTime() < stratDate.value.getTime() + oneDateNumber
            }
        }
    }
    //开始日期清空,联动把结束日期也清空
    watch(
        () => stratDate.value,
        val => {
            endDate.value = null
            endDateDisabled.value = true
            if (val) {
                endDateDisabled.value = false
                //给父组件分发事件
                emits('startChange', val)
            }
        }
    )
    //结束日期监听
    watch(
        () => endDate.value,
        val => {
            if (val !== null) {
                emits('endChange', {
                    stratDate: stratDate.value,
                    endDate: val,
                })
            }
        }
    )
    </script>
    
    <style lang="scss" scoped>
    .bs-wrapper {
        display: flex;
    }
    .box {
        &__start {
            margin-right: 0.2rem;
        }
    }
    </style>
    

    新建src\components\baseline\chooseDate\index.ts

    import { App } from 'vue'
    import ChooseDate from './src/index.vue'
    
    export { ChooseDate }
    
    //组件可通过use的形式使用
    export default {
        ChooseDate,
        install(app: App) {
            app.component('bs-choose-date', ChooseDate)
        },
    }
    
    

    修改src\components\baseline\index.ts

    import { App } from 'vue'
    import ChooseArea from './chooseArea'
    import ChooseIcon from './chooseIcon'
    import Container from './container'
    import Trend from './trend'
    import Notification from './notification'
    import List from './list'
    import Menu from './menu'
    import Progress from './progress'
    import ChooseTime from './chooseTime'
    import ChooseDate from './chooseDate'
    
    const components = [
        ChooseArea,
        ChooseIcon,
        Container,
        Trend,
        Notification,
        List,
        Menu,
        Progress,
        ChooseTime,
        ChooseDate,
    ]
    export {
        ChooseArea,
        ChooseIcon,
        Container,
        Trend,
        Notification,
        List,
        Menu,
        Progress,
        ChooseTime,
        ChooseDate,
    }
    
    //组件可通过use的形式使用
    export default {
        install(app: App) {
            components.map(item => {
                app.use(item)
            })
        },
        ChooseArea,
        ChooseIcon,
        Container,
        Trend,
        Notification,
        List,
        Menu,
        Progress,
        ChooseTime,
        ChooseDate,
    }
    
    

    修改src\views\baseline\chooseTime\index.vue

    <template>
        <div>
            <div>
                <span style="display: inline-block; margin-bottom: 0.1rem">
                    时间选择:
                </span>
                <bs-choose-time
                    @startChange="startChange"
                    @endChange="endChange"
                ></bs-choose-time>
            </div>
            <div>
                <span style="display: inline-block; margin: 0.1rem 0">
                    时间选择(增加element其他属性):
                </span>
                <bs-choose-time
                    :startOptions="startOptions"
                    :endOptions="endOptions"
                ></bs-choose-time>
            </div>
            <div>
                <span style="display: inline-block; margin: 0.1rem 0">
                    日期选择:
                </span>
                <bs-choose-date
                    @startChange="startDateChange"
                    @endChange="endDateChange"
                ></bs-choose-date>
            </div>
            <div>
                <span style="display: inline-block; margin: 0.1rem 0">
                    日期选择 (过去时间):
                </span>
                <bs-choose-date
                    :disableBeforeToDay="false"
                    :disableAfterToDay="true"
                    :selectToDay="true"
                    @startChange="startDateChange"
                    @endChange="endDateChange"
                ></bs-choose-date>
            </div>
            <div>
                <span style="display: inline-block; margin: 0.1rem 0">
                    日期选择(未来时间):
                </span>
                <bs-choose-date
                    :disableBeforeToDay="true"
                    :disableAfterToDay="false"
                    :selectToDay="true"
                    @startChange="startDateChange"
                    @endChange="endDateChange"
                ></bs-choose-date>
            </div>
            <div>
                <span style="display: inline-block; margin: 0.1rem 0">
                    日期选择(过去时间,不能当天到当天):
                </span>
                <bs-choose-date
                    :disableBeforeToDay="false"
                    :disableAfterToDay="true"
                    :selectToDay="false"
                    @startChange="startDateChange"
                    @endChange="endDateChange"
                ></bs-choose-date>
            </div>
            <div>
                <span style="display: inline-block; margin: 0.1rem 0">
                    日期选择(自定义属性):
                </span>
                <bs-choose-date
                    :startOptions="startOptions"
                    :endOptions="endOptions"
                    @startChange="startDateChange"
                    @endChange="endDateChange"
                ></bs-choose-date>
            </div>
        </div>
    </template>
    <script lang="ts" setup>
    interface timeValue {
        startTime: string
        endTime: string
    }
    interface dateValue {
        stratDate: Date
        endDate: Date
    }
    const startChange = (value: string) => {
        console.log('startChange', value)
    }
    const endChange = (value: timeValue) => {
        console.log('endChange', value)
    }
    const startDateChange = (value: Date) => {
        console.log('startChange', value)
    }
    const endDateChange = (value: dateValue) => {
        console.log('endChange', value)
    }
    const startOptions = { size: 'mini', clearable: false }
    
    const endOptions = { size: 'mini', clearable: false }
    </script>
    <style lang="scss" scoped></style>
    
    

    效果如下:


    image.png
    image.png

    相关文章

      网友评论

        本文标题:【Vue3+Vite+TS】11.0 组件八:时间选择组件

        本文链接:https://www.haomeiwen.com/subject/bcogqrtx.html