暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

深入解析Day.js在Vue项目中的高效日期处理实践

原创 浮游 2024-11-14
158

Day.js是一个轻量级的JavaScript时间库,用于解析、验证、操作和格式化日期。它的API设计风格与Moment.js类似,但是它的体积更小,只有2KB,使得它在前端项目中非常受欢迎。Day.js支持链式操作,易于阅读和理解,同时它也是不可变的,这意味着Day.js对象操作后会返回一个新的Day.js实例。

效果大致如下:

image.png

image.png

在上述代码中,Day.js被用于处理日期和时间,主要体现在以下几个方面:

引入和配置

import dayjs from 'dayjs' import isoWeek from 'dayjs/plugin/isoWeek' dayjs.extend(isoWeek)
复制

这段代码首先引入了Day.js库,然后引入了isoWeek插件。isoWeek插件用于处理ISO周相关的操作。通过dayjs.extend(isoWeek)来扩展Day.js,使其支持ISO周的相关功能。

获取当前日期的ISO周的开始日期

const getWeekStart = (date: string | null) => { if (!date) return null return dayjs(date).startOf('isoWeek').format('YYYY-MM-DD') }
复制

getWeekStart函数接受一个日期字符串作为参数,使用dayjs将其转换为Day.js对象,然后调用startOf('isoWeek')来获取该周的第一天(通常是周一),最后通过format('YYYY-MM-DD')将日期格式化为年-月-日的格式。

计算一周内每一天的日期

const getWeekDays = () => { const weekStart = getWeekStart(selectedWeek.value) weekDays.value = days.map((day, index) => { const date = new Date(weekStart) date.setDate(date.getDate() + index) return { key: day, label: `${dayLabels[day]}\n\n${date.getMonth() + 1}/${date.getDate()}`, date: date.toISOString().split('T')[0] } }) }
复制

getWeekDays函数计算选定周的每一天的日期,并将其存储在weekDays响应式变量中。它首先获取周的开始日期,然后遍历每一天,通过new Date(weekStart)创建一个日期对象,并使用setDate方法加上索引值来获取该周的每一天的日期。

日期选择器的变化处理

const handleWeekChange = (value: any) => { selectedWeek.value = value fetchData(getWeekStart(selectedWeek.value), getDateAfterSevenDays(selectedWeek.value)) getWeekDays() }
复制

handleWeekChange函数作为日期选择器变化的事件处理函数,当用户选择一个新的周时,它会更新selectedWeek的值,并调用fetchData函数来获取新周的数据,同时调用getWeekDays来更新周内每天的日期。

格式化日期

selectedWeek.value = dayjs().subtract(0, 'week').startOf('isoWeek').format('YYYY-MM-DD')
复制

这段代码用于设置默认选中的周为当前周。它使用dayjs()获取当前日期的Day.js对象,然后通过subtract(0, 'week')获取当前周,接着通过startOf('isoWeek')获取周的开始日期,最后通过format('YYYY-MM-DD')格式化日期。

Day.js的这些特性在上述代码中得到了广泛的应用,展示了如何使用Day.js来处理复杂的日期逻辑。它的轻量级和易用性使得它成为处理日期和时间的理想选择。

具体代码实现

<template> <div class="pad20"> <el-date-picker class="mb20" v-if="weekDays.length" v-model="selectedWeek" type="week" format="YYYY 第 ww 周" placeholder="选择周" :first-day-of-week="1" @change="handleWeekChange" /> <el-table v-if="weekDays && weekDays.length > 0" :class="{ 'no-filter-icon': executorFilterOptions && executorFilterOptions.length == 0 }" size="medium" :header-cell-style="{ background: '#f5f7fa' }" :data="processedData" style="width: 100%" > <el-table-column label="执行人" width="120" fixed :filters="executorFilterOptions && executorFilterOptions.length ? executorFilterOptions : null" :filter-method="filterExecutor" > <template #default="prop"> <router-link :to="`/planHour/${prop.row.executorId}`" class="cur-p">{{ prop.row.executorName }}</router-link> </template> </el-table-column> <el-table-column label="总计工时" width="180" fixed prop="weekTotal" sortable> <template #default="prop"> <el-progress class="custom-progress-bar" :color="customColorMethod(prop.row.weekTotal)" :percentage="parseFloat(((prop.row.weekTotal / 40) * 100).toFixed(2))" > <span text>{{ prop.row.weekTotal }}</span> </el-progress> </template> </el-table-column> <el-table-column v-for="day in weekDays" :key="day.date" :label="day.label"> <template #default="scope"> {{ scope.row.weekData[day.key] }} </template> </el-table-column> </el-table> </div> </template> <script lang="ts" setup> import { computed, onMounted, ref, reactive, toRefs } from 'vue' import { xxxApi } from '@/apis' import { useRouter } from 'vue-router' import useMapStore from '@/compositions/mapStore' import dayjs from 'dayjs' import isoWeek from 'dayjs/plugin/isoWeek' import 'dayjs/locale/zh-cn' import { cbSuccess, cloneDeep, rules, checkTypeTemplate } from '@/utils' import { Plan, Common } from '@/interfaces' import useAdmq from '@/compositions/admq' import { ElMessage } from 'element-plus' import ESDialogVue from '@/components/ESDialog.vue' const { user, isSys, isDba, isPA } = useMapStore() const router = useRouter() dayjs.extend(isoWeek) const originalData = ref([]) const selectedWeek = ref(null) const weekDays = ref([]) const state = reactive({ executor: {} as any, taskTimeTotalList: [] as any, planShow: false, planInfo: {} as Plan, team: Array<Common>(), teams: [ { executorId: undefined, taskTime: undefined, remarks: undefined } ] as any, newcoms: [], canSave: true, users: [], copyId: undefined, id: undefined, executorId: undefined }) const { planInfo, teams, planShow, newcoms } = toRefs(state) const fetchData = async (start: string, end: string) => { let _params = { startDate: start, endDate: end } let { data } = await xxxApi(_params) if (Array.isArray(data)) originalData.value = data } const { formRef, onSubmit, operate, onconfirm } = useAdmq(fetchData) const setType = (path: any) => { router.push(path) } const executorFilterOptions = computed(() => { const executors = new Set() originalData.value.forEach(person => { executors.add({ text: person.executorName, value: person.executorId }) }) return Array.from(executors) }) const filterExecutor = (value: any, row: any) => { return row.executorId === value } const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] const dayLabels = { Mon: '周一', Tue: '周二', Wed: '周三', Thu: '周四', Fri: '周五', Sat: '周六', Sun: '周日' } as any const getWeekStart = (date: string | null) => { if (!date) return null return dayjs(date).startOf('isoWeek').format('YYYY-MM-DD') } function getDateAfterSevenDays(dateString: string) { return dayjs(dateString).add(6, 'day').format('YYYY-MM-DD') } const processedData = computed(() => { const weekStart = getWeekStart(selectedWeek.value) if (!weekStart) return [] return originalData.value.map(person => { const weekData = {} as any let weekTotal = 0 days.forEach((day, index) => { const date = new Date(weekStart) date.setDate(date.getDate() + index) const dateString = date.toISOString().split('T')[0] const dayData = person.taskTimeTotalList.find((item: any) => item.date === dateString) const hours = dayData ? dayData.hours : 0 weekData[day] = hours weekTotal += hours }) weekTotal = Number(weekTotal.toFixed(1)) return { executorId: person.executorId, executorName: person.executorName, weekTotal, weekData } }) }) const setDefaultWeek = () => { selectedWeek.value = dayjs().subtract(0, 'week').startOf('isoWeek').format('YYYY-MM-DD') if (selectedWeek.value) getWeekDays() } const getWeekDays = () => { const weekStart = getWeekStart(selectedWeek.value) weekDays.value = days.map((day, index) => { const date = new Date(weekStart) date.setDate(date.getDate() + index) return { key: day, label: `${dayLabels[day]}\n\n${date.getMonth() + 1}/${date.getDate()}`, date: date.toISOString().split('T')[0] } }) } const handleWeekChange = (value: any) => { selectedWeek.value = value fetchData(getWeekStart(selectedWeek.value), getDateAfterSevenDays(selectedWeek.value)) getWeekDays() } const customColorMethod = (weekTotal: any) => { let item = weekTotal if (item >= 48) { return '#2196F3' } else if (item < 48 && item >= 40) { return '#388E3C' } else if (item < 40 && item >= 32) { return '#67c23a' } else if (item < 32 && item >= 20) { return '#e6a23c' } else if (item < 20) { return '#f56c6c' } } onMounted(() => { setDefaultWeek() fetchData(getWeekStart(selectedWeek.value), getDateAfterSevenDays(selectedWeek.value)) }) </script>
复制
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论