前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试题要求用uniapp/vue3写一个日程组件?那不是有手就行?

面试题要求用uniapp/vue3写一个日程组件?那不是有手就行?

原创
作者头像
公众号:前端cssandjs
修改2024-05-06 18:26:11
1060
修改2024-05-06 18:26:11

  • 背景

众所周知,我最近在找工作,然后就遇到了一道面试题(需要面试题和简历一起提交)。具体要求如下:

image.png
image.png

需求分析

  • 这是一个日程管理程序, 所以需要一个日历,需要可以录入日程
  • 需要有月度和天的展示,月度用一个日历,天用时间线
  • 日程可以录入标题,时间,备注等,可以删除

看着这些需求,鉴于我有限的审美能力,我决定还是借鉴一个吧。所以目光锁定了ios的系统日程表,审美在线。

页面需求

image.png
image.png

这里暂时就定为2个页面和一个弹窗

  • 一个月显示的页面。显示当月所有日期,如果当前日期有日程,则显示一个红点。激活的当天,显示为红色背景。
  • 一个日显示的页面。以时间轴显示当天所有日程,按照0:00-24:00分布。
  • 一个新建日程页面,为了简化步骤,先以类似腾讯会议的形式,只允许添加某一天的时间。同时这个弹窗也是新增/编辑/删除/查看四合一的页面。这样就大大简化了所需的书写代码。

相关依赖

  • uni-app
  • pinia
  • dayjs
  • uni-ui核心编码部分

日历部分

image.png
image.png

这里的日历计算方式,就是先拿到我们的月份,然后获取第一天。因为日历显示的是周日开始,所以根据第一天是周几,然后向前减去几天。

代码语言:js
复制
  // date 为当前需要计算的日期
  const dateObj = dayjs(date);
  const monthStart = dateObj.startOf("month");
  const dayOfWeek = monthStart.day();
  const fistDay = monthStart.subtract(dayOfWeek, "day");

这样我们就拿到了日历的开始第一天的日期。然后进行遍历,一般情况下,日历显示42天,开始不足的部分由上月补足,结尾不足的部分由下月补足。补足的部分要用灰色显示。

代码语言:js
复制
  // 需要生成一个6*7的数组
  const days: CurrentDate[][] = new Array(6).fill(0).map(() => []);
  
  for (let i = 0; i < 42; i++) {
    const currentDate = fistDay.add(i, "day");
    // 每7天即添加到下一个数组
    days[Math.floor(i / 7)].push({
      date: currentDate, 
      showDate: currentDate.date(),  
      formatDate: currentDate.format("YYYY-MM-DD"), 
      isCurrtentMonth: currentDate.month() === dateObj.month(),
      isToday: currentDate.isSame(dayjs(), "day"), 
    });
  }

整体的数据结构如下

代码语言:ts
复制
export type CurrentDate = {
  date: dayjs.Dayjs; // 当前时间的原始时间
  showDate: number; // 显示在日历中的1-31
  isCurrtentMonth?: boolean;  //是否为当月
  isToday: boolean; // 是否为今天
  formatDate: string; // 年月日的完整展示,这里用来跟后面的是否有日程做比对,如果有会在日历中展示一个小红点
};

渲染数据,并做如下判断:

  • 如果isCurrtentMonth为false,则不是当月,用灰色显示
  • 如果isToday为true,则为今天,用背景红色展示
  • 如果时间列表中有formatDate的数据,则展示一个小点,代表今天有日程

数据组织部分

核心的pinia store,包括以下几个state

  • viewStatus:'mouth'|'day' 代表了视图的切换,目前就两个视图,一个月,一个日
  • day:dayjs.Dayjs 代表当前所在的时间,在月页面即哪个月,在日页面为哪一周
  • list:List 代表了所有事件存储的列表,这个部分下面再单独说一下
  • editInfo:Data 代表了编辑所使用的数据

list根据日期来进行分类

整体结构为

代码语言:json
复制
{
    "2024-05-15": {
        "10:00-12:00": [
          {
            title: "Meeting",
            startTime: "10:00",
            date: "2024-04-15",
            endTime: "12:00",
            remark: "Discuss the plan for the next quarter",
          },
          {
            title: "Interview",
            startTime: "10:00",
            endTime: "12:00",
            date: "2024-04-15",
            remark: "Interview candidate for the front-end position",
          },
        ],
}

这里根据日期对整体做一个初步的map,然后根据每个日程的时间范围,做二次map,这样相同高度的日程就可以聚合在一起,而不同时间的日程,就可以显示在不同的位置。

每组数据,跟日常中的相关字段对应

image.png
image.png

日的渲染部分

image.png
image.png

根据list进行遍历,对于具体日程,根据"开始时间-结束时间"这个key进行具体的划分。然后计算出当前这个时间段的高度,以及相对于顶部的位置。

代码语言:js
复制
const dateList = computed(() => {
    const { list, day } = store
    const dayText = dayjs(day).format('YYYY-MM-DD')
    const dateList = list[dayText] // 获取当天日程信息
    
    return Object.keys(dateList).map(key => {
        const item = dateList[key]
        const [startHour, endHour] = key.split('-') //开始时间结束时间拆分
        return {
            list: item,
            top: getTop(startHour) + '%', //顶部top
            height: (getTop(endHour) - getTop(startHour)) + '%' 时间差的高度

        }
    })

})

function getTop(time, isEnd = false) {
    const [hour, minute] = time.split(':')
    const top = (hour * 60 + minute * 1) / 1440 * 100 // 根据时和分,转化后,除以24小时的时间,算出百分比
    return top
}

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求分析
  • 页面需求
  • 相关依赖
    • 日历部分
      • 数据组织部分
        • 日的渲染部分
        相关产品与服务
        腾讯会议
        腾讯会议(Tencent Meeting)为企业打造专属的会议能力,卓越的音视频性能,丰富的会议协作能力,坚实的会议安全保障,提升协作效率,满足大中小会议全场景需求。您可以使用腾讯会议进行远程音视频会议、在线协作、会管会控、会议录制、指定邀请、布局管理、同声传译等。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档