【Vue3+Vite】实现周计划日程打卡表

效果图:

请添加图片描述

实现功能:显示当前一周的任务表格、评定优先级、通过点击✔或者✘来进行任务打卡,显示已完成或者未完成,展示任务详情、任务时间…

script
<script setup>
import { onMounted, ref } from "vue";
import moment from "moment";
// 头部星期
const weeks = ref(["周一", "周二", "周三", "周四", "周五", "周六", "周日"]);
// 日程打卡内容
const timePeriodList = ref( [
      {
        startTime: "13:30:00",
        endTime: "15:30:00",
        cate: "读一篇英语文章,复习昨天的单词,新记50个单词",
        commnd_type: "学习任务",
        id: 22,
        missionTime: "2024-07-23",
        name: "英语作业",
        period: 1,
        priority: 1,
        isItCompleted: null,
      },
      {
        startTime: "9:10:00",
        endTime: "9:30:00",
        cate: "打扫卧室卫生,洗被子",
        commnd_type: "日常任务",
        id: 23,
        missionTime: "2024-07-25",
        name: "家务",
        period: 0,
        priority: 0,
        isItCompleted: null,
      }, 
      {
        startTime: "17:30:00",
        endTime: "18:30:00",
        cate: "热身运动、跑步三公里、俯卧撑100个",
        commnd_type: "日常任务",
        id: 24,
        missionTime: "2024-07-25",
        name: "锻炼",
        period: 0,
        priority: 0,
        isItCompleted: null,
      },
      {
        startTime: "13:30:00",
        endTime: "15:30:00",
        cate: "读一篇英语文章,复习昨天的单词,新记50个单词",
        commnd_type: "学习任务",
        id: 25,
        missionTime: "2024-07-26",
        name: "英语作业",
        period: 1,
        priority: 1,
        isItCompleted: null,
      }
    ],
);
// 时间
const systemDate = new Date();
// 月份
const months = ref([]);
const dealDate = (date) => {
  months.value = [""];
  getWeek(date);
  const curSystem = moment(new Date()).format("YYYY-MM-DD");
  months.value.forEach((item) => {
    item.isCurDate = item.date === curSystem;
  });
};
const getWeek = (time) => {
  let week = time.getDay() - 1;
  if (week === -1) {
    week = 6;
  }
  time = addDate(time, week * -1);
  for (let i = 0; i < 7; i++) {
    const { year, month, day } = formatDate(i === 0 ? time : addDate(time, 1));
    months.value.push({
      date: `${year}-${month}-${day}`,
      showDate: `${month}-${day}`,
      week: time.getDay() == 0 ? 7 : time.getDay(),
    });
  }
  months.value.splice(0, 1);
};

/**
 * 处理日期
 * @param date
 * @param n
 * @returns {*}
 */
const addDate = (date, n) => {
  date.setDate(date.getDate() + n);
  return date;
};
// 日期格式处理
const formatDate = (date) => {
  var year = date.getFullYear();
  var months = date.getMonth() + 1;
  var month = (months < 10 ? "0" + months : months).toString();
  var day = (
    date.getDate() < 10 ? "0" + date.getDate() : date.getDate()
  ).toString();
  return {
    year,
    month,
    day,
  };
};

onMounted(() => {
  dealDate(systemDate);
});
</script>

template
<template>
  <div class="task-table">
    <div class="week-table">
      <div class="header">
        <div class="header-date">
          <span
            v-for="(item, index) of months"
            :key="index"
            class="day-item"
            :class="{ isCurDate: item && item.isCurDate }"
          >
          {{ weeks[index] }}
          <br>
            {{
              `${
                item && item.isCurDate
                  ? (item && item.showDate + "(今天)") || ""
                  : (item && item.showDate) || ""
              }`
            }}
          </span>
        </div>
      </div>
      <div class="timePeriodList">
          <template v-if="timePeriodList.length > 0">
              <div class="week-day">
                <!-- 循环显示每周的日期-->
                <template v-for="(month, m_index) of months">
                  <!-- v-if="month" 去除数据处理的时候移除数组第一个为empty的问题-->
                  <div v-if="month" :key="`month${m_index}`" class="things">
                    <template v-for="(thing, t_index) of timePeriodList">
                      <div
                        v-if=" thing.missionTime === month.date"
                        :key="`thing${t_index}`"
                        class="thing-item outdated"
                      >
                        <el-card class="box-card">
                          <div Slots="header" class="clearfix">
                            <p style="font-size: 18px;">{{ thing.name }}</p>
                            <!-- 任务打卡 -->
                            <div>
                                <el-tag v-if="thing.isItCompleted" effect="dark" size="small" :type="thing.isItCompleted== 1?'success':'danger'">{{ thing.isItCompleted== 1? '已完成': '未完成'}}</el-tag>
                                <el-radio-group v-else v-model="thing.isItCompleted">
                                  <el-radio :value="1"></el-radio>
                                  <el-radio :value="2"></el-radio>
                                </el-radio-group>
                              </div>
                          </div>
                          <!-- 展示任务内容 -->
                          <div class="text item">
                            <p>
                              <el-tag type="primary">{{ thing.commnd_type }}</el-tag>
                            </p>

                            <p>开始时间:{{ thing.startTime }}</p>
                            <p>结束时间:{{ thing.endTime }}</p>
                            <el-tooltip placement="top" effect="customized">
                              <template #content> {{ thing.cate }} </template>
                              <p>任务内容:{{ thing.cate }}</p>
                            </el-tooltip>
                            <p>优先级:<el-tag :type="thing.priority===1?'warning':'info'">{{ thing.priority===1?'重要':'一般' }}</el-tag></p>
                          </div>
                        </el-card>
                      </div>  
                    </template>
                  </div>
                </template>
              </div>
          </template>
          <div class="noMore" v-else><span>暂无数据</span></div>
      </div>
    </div>
  </div>
</template>

style
<style>
.week-table {
  display: flex;
  flex-direction: column;
  height: 400px;
}
.header {
  width: 100%;
  height: 80px;
  background: #eaedf2;
  display: flex;
  flex-direction: column;
  align-items: center;
  border-bottom: 1px solid #eaedf2;
  box-sizing: border-box;
}
.header-date{
  width: 100%;
  height: 40px;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 1rem;
}
.day-item {
  min-width: 14rem;
  flex: 1;
  height: 100%;
  font-size: 18px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-weight: bold;
  color: #000;
}
.timePeriodList {
  width: 100%;
}

.week-day {
  width: 100%;
  display: flex;
  justify-content: center;
}
.things {
  min-width: 14rem;  
  flex: 1;
  display: flex;
  flex-direction: column;
  border-left: 1px solid #eaedf2;
  border-bottom: 1px solid #eaedf2;
  box-sizing: border-box;
}
.timePeriodList:last-child {
  border-right: 1px solid #eaedf2;
}

.thing-item {
  border-bottom: 1px solid #eaedf2;
  display: flex;
  font-size: 14px;
  flex-direction: column;
  justify-content: space-around;
  color: #fff;
  background: #ff6200;
  min-height: 90px;
  padding: 4% 0;
  cursor: pointer;
  box-sizing: border-box;
}


.outdated {
  display: flex;
  align-items: center;
  color: #fff;
  background: transparent;
  margin: 0.5rem;
}
.isCurDate {
  color: #409EFF !important;
}

.noMore {
  min-height: 200px;
  padding: 2%;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid rgba(156, 173, 173, 0.3);
  color: #9cadadb7;
  box-sizing: border-box;
}

.text p {
  font-size: 14px;
  margin-bottom: 10px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}
.el-popper.is-customized .el-popper__arrow::before {
  background: linear-gradient(45deg, #b2e68d, #bce689);
  right: 0;
}
.el-popper.is-customized {
  padding: 6px 12px;
  background: linear-gradient(90deg, rgb(159, 229, 151), rgb(204, 229, 129));
}

.item {
  overflow: auto;
}
.clearfix {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.clearfix p {
  white-space: nowrap; /* 让文本不换行 */
  overflow: hidden; /* 隐藏溢出的文本 */
  text-overflow: ellipsis; /* 显示省略号 */

}
.clearfix .el-radio {
  margin-right: 0;
}

.box-card {
  width: 13rem;
  height: 18rem;

}
</style>
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Electron是一个开源框架,用于构建跨平台的桌面应用程序,结合Vue.js和Vite(一个快速的前端构建工具)可以让您创建现代、高性能的Web视层,嵌入到 Electron 应用中。RTSP(Real-Time Streaming Protocol)是一种网络协议,用于实时视频流传输。 要在 Electron + Vue3 + Vite实现 RTSP 播放,您可以按照以下步骤操作: 1. **安装依赖**: - 安装 `vue-video-player` 或类似的库,它提供了处理媒体流的功能,如 `vue-streaming-api`。 - 如果需要,安装支持 RTSP 解码的库,比如 `fluent-ffmpeg` 或 `mediasoup-client`。 ```bash npm install vue-video-player fluent-ffmpeg --save ``` 2. **设置配置**: 在项目中创建一个配置文件(例如 `config.js`),用于管理 RTSP 地址等信息。 ```javascript export default { rtspsource: 'rtsp://your_rtspserver_url/stream' } ``` 3. **在 Vue 组件中使用**: 使用 Vue 插件或组件内的方法加载并播放 RTSP 流。例如,使用 `vue-video-player`: ```html <template> <div id="player"> <VideoPlayer v-bind:src="config.rtspsource"></VideoPlayer> </div> </template> <script> import VideoPlayer from 'vue-video-player'; import { defineComponent, ref } from 'vue'; import config from '@/config'; export default defineComponent({ components: { VideoPlayer, }, setup() { const player = ref(null); // 当组件挂载后尝试播放 mounted() { player.value.play(); } return { player, }; }, }); </script> ``` 4. **错误处理**: 添加错误处理代码来捕获并处理播放过程中可能出现的问题,如连接失败、编码不兼容等。 5. **优化和调整**: 根据应用需求可能还需要对视频质量、缓冲策略等进行优化,并确保在不同平台上运行稳定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值