用 ElementPlus 的日历组件 Calendar 自定义渲染

文章目录

    • 需求
    • 分析
      • 1. 英文改为中文
      • 2. 修改样式
      • 3. 自定义头部
      • 4. 增删改功能接入

需求

使用 ElementPlus中的 Calendar 组件完成自定义渲染

分析

1. 英文改为中文

转为中文的方式:用 ElementPlus的日历组件如何改为中文

2. 修改样式

在这里插入图片描述

  • 附源码
<template>
  <el-calendar>
    <template #date-cell="{ data }">
      <el-row :class="data.isSelected ? 'is-selected' : 'sds'">
        {{ data.day.split('-').slice(1).join('-') }}
        {{ data.isSelected ? '✔️' : '' }}
      </el-row>
      <div v-for="(item, index) in textContent(data.day)" :key="index">
                <e-row>
                  <el-col class="center">
                    <el-tag type="warning" class="tag">
                      <el-row v-if="item.xianyue == 0">
                        <el-col :span="17" class="tag">
                          <span>当日限约</span>
                        </el-col>
                        <el-col :span="1"></el-col>
                        <el-col :span="6" class="tag2">
                          <span>0</span>
                        </el-col>
                      </el-row>
                      <el-row v-else>
                        <el-col :span="17" class="tag">
                          <span>当日限约</span>
                        </el-col>
                        <el-col :span="1"></el-col>
                        <el-col :span="6" class="tag2">
                          <span>{{ item.xianyue }}</span>
                        </el-col>
                      </el-row>
                    </el-tag>
                  </el-col>
                </e-row>
                <el-row
                  style="margin-top: 10px"
                  class="yuyue"
                  v-if="item.yiyue && item.sy == 0"
                >
                  <el-col :span="11" class="center">
                    <span>已约</span
                    ><span class="center2" style="">0</span></el-col
                  >
                  <el-col :span="2" class="center">|</el-col>
                  <el-col :span="11" class="center">
                    <span>剩余</span><span class="center2">0</span></el-col
                  >
                </el-row>
                <el-row style="margin-top: 10px" class="yuyue" v-else>
                  <el-col :span="11" class="center">
                    <span>已约</span
                    ><span class="center2" style="">{{
                      item.yiyue
                    }}</span></el-col
                  >
                  <el-col :span="2" class="center">|</el-col>
                  <el-col :span="11" class="center">
                    <span>剩余</span
                    ><span class="center2">{{ item.sy }}</span></el-col
                  >
                </el-row>
              </div>

    </template>
  </el-calendar>
</template>

<style>
.is-selected {
  color: #1989fa;
}
  
  
</style>

<style scoped >
 
:deep .el-calendar__body {
  padding: 4px 20px 35px;
}
:deep .el-calendar-table thead th {
  color: #ffab11;
  font-weight: bold;
  font-size: 25px;
}
.tag {
  display: flex;
  align-items: center;
  height: 2.5vh;
  justify-content: center;
}
.tag2 {
  display: flex;
  align-items: center;
  height: 2.5vh;
  justify-content: center;
  font-size: 18px;
}
.aaa .is-selected .yuyue {
  color: #ffab11;
}
.aaa .datastyle {
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 3rem;
  color: #353636;
  font-weight: 600;
}
:deep .el-calendar-table .el-calendar-day:hover {
  background-color: #faecd8;
}
:deep .el-calendar {
  --el-calendar-selected-bg-color: #faecd8;
}
.aaa .is-selected .datastyle {
  color: #ffab11;
}
.aaa .prev .datastyle {
  color: #c4c5c8;
}
.aaa .next .datastyle {
  color: #c4c5c8;
}
:deep .el-calendar {
  --el-calendar-cell-width: 130px;
}
.center {
  display: flex;
  justify-content: center;
  align-items: center;
}
.center2 {
  display: flex;
  justify-content: center;
  align-items: center;
  color: #ffab11;
  margin-left: 5px;
  font-size: 20px;
}
:deep .el-calendar__header {
  justify-content: center;
}
</style>

<script setup lang="ts">
import { ref, reactive, toRefs, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
  
  const state = reactive({
      tableData: [],
        //测试数据
      calendarData: [
        {
          day: "2022-11-04",
          xianyue: 400,
          yiyue: 5,
          sy: 1,
        },
        {
          day: "2022-11-05",
          xianyue: 500,
          yiyue: 5,
          sy: 1,
        },
        {
          day: "2022-11-06",
          xianyue: 200,
          yiyue: 5,
          sy: 1,
        },
        {
          day: "2022-11-07",
          xianyue: 0,
          yiyue: 0,
          sy: 0,
        },
      ],
    });
  
  
  //处理日期获取后台数据动态渲染上去
    const textContent = (date) => {
        //当前date是拿到上面日历组件当前的日期值 根据该值去筛选测试数据找到对应各个日期下对应的数据return出去
        console.log(date, 1111);
        return state.calendarData.filter((item) => {
          return date === item.day;
        });
      };

</script>

3. 自定义头部

在这里插入图片描述

<el-calendar v-model="value" ref="calendar">
   <template #header="{ date }">
       <el-button-group>
           <el-button size="small" @click="selectDate('prev-year')">
               上一年
           </el-button>
           <el-button size="small" @click="selectDate('prev-month')">
               上个月
           </el-button>
       </el-button-group>
       <span>{{ date }}</span>
       <el-button-group>
           <el-button size="small" @click="selectDate('today')">今天</el-button>
           <el-button size="small" @click="selectDate('next-month')">
               下个月
           </el-button>
           <el-button size="small" @click="selectDate('next-year')">
               下一年
           </el-button>
       </el-button-group>
   </template>
<el-calendar/>



const value = ref(new Date());
const dateList = ref([])
const calendar = ref();
const selectDate = (val) => {
    dateList.value.length = 0
    calendar.value.selectDate(val);
};
function handleMonthChange(date) {
    dateList.value.push(date)
    // date 是切换后的日期,根据这个日期来计算开始日期和结束日期
    // const year = date.getFullYear();
    // const month = date.getMonth();
    // const startDate = new Date(year, month, 1); // 开始日期
    // const endDate = new Date(year, month + 1, 1); // 结束日期


    //根据开始日期和结束日期来查询数据,然后更新视图
    // ...
}

4. 增删改功能接入

在这里插入图片描述

<template>
    <div class="container my-container">
        <a-card :bordered="false" :style="{ width: '100%' }">
            <el-calendar v-model="value" ref="calendar">
                <template #header="{ date }">
                    <el-button-group>
                        <el-button size="small" @click="selectDate('prev-year')">
                            上一年
                        </el-button>
                        <el-button size="small" @click="selectDate('prev-month')">
                            上个月
                        </el-button>
                    </el-button-group>
                    <span>{{ date }}</span>
                    <el-button-group>
                        <el-button size="small" @click="selectDate('today')">今天</el-button>
                        <el-button size="small" @click="selectDate('next-month')">
                            下个月
                        </el-button>
                        <el-button size="small" @click="selectDate('next-year')">
                            下一年
                        </el-button>
                    </el-button-group>
                </template>
                <template #date-cell="{ data }">
                    <div class="calendar-day">
                        <div :class="data.isSelected ? 'is-selected' : ''">
                            {{ data.day.split('-').slice(1).join('-') }}
                        </div>
                        {{ handleMonthChange(data.day) }}
                        <p class="duty-text">
                            值班人员:
                            <span v-for="item in tableData" :key="item.id">
                                <span v-if="item.dutyDate == data.day">
                                    {{ item.dutyUser }}
                                </span>
                            </span>
                        <div>
                            <a-button size="mini" type="text" @click="handleEdit(data)"
                                style="color: #58a7fe;">编辑</a-button>
                            <a-popconfirm content="确定要删除" @ok="handleDelete(data)">
                                <a-button size="mini" type="text" style="color: #58a7fe;">删除</a-button>
                            </a-popconfirm>
                        </div>
                        </p>
                    </div>
                </template>
            </el-calendar>
        </a-card>
        <a-modal v-model:visible="visible" :title="title" draggable :on-before-ok="handleOk" :mask-closable="false">
            <a-form ref="formRef" :model="editForm" :label-col-props="{ span: 5 }" :wrapper-col-props="{ span: 16 }">
                <a-form-item field="deptId" label="部门:">
                    <el-cascader v-model="editForm.deptId" style="min-width: 350px;" ref="cas"
                        :options="typeList.deptList" :props="props" clearable collapse-tags @change="cascaderChange"
                        placeholder="请选择">
                    </el-cascader>
                </a-form-item>
                <a-form-item field="userId" label="值班人:" :rules="[
            {
                required: true,
                message: '请选择',
            },
        ]">
                    <el-select style="min-width: 350px;" v-model="editForm.userId" placeholder="请选择">
                        <el-option v-for="(item, index) in typeList.userList" :key="index" :label="item.userName"
                            :value="item.userId" />
                    </el-select>
                </a-form-item>

            </a-form>
        </a-modal>
    </div>
</template>

<script lang="ts" setup>
import { onMounted, ref, watch, watchEffect, defineComponent, computed } from 'vue';
import { Message } from '@arco-design/web-vue';
import {
    getDutyPlanData as getInfo,
    getdept,
    getUser,
    getUserData,
    addDutyPlanData as addData,
    editDutyPlaneData as editData,
    deleteDutyPlanData as deleteData,
} from '@/api/common-management'
import { handleTree } from "@/utils/common-tools";

function findItemUser(data) {
    const currentObj = typeList.value.userLists.find(item => {
        return item.user_id == data
    })
    if (currentObj) {
        return currentObj.user_name
    }
}

const value = ref(new Date());
// 编辑
const resetEditForm = () => {
    return {
        deptId: null,
        userId: null
    }
}
const editForm = ref(resetEditForm())
const visible = ref(false)
const title = ref('')
// 编辑
function handleEdit(val) {
    editForm.value = resetEditForm()
    getInfo({ dutyDate: val.day }).then(res => {
        if (res.rows.length) {
            editForm.value = res.rows[0]
            title.value = '编辑'
        } else {
            editForm.value.dutyDate = val.day
            title.value = '添加'
        }
    })
    visible.value = true
}
const formRef = ref()
const handleOk = async () => {
    const res = await formRef.value?.validate();
    if (!res) {
        if (title.value == '编辑') {
            const tempData = {
                dutyDate: editForm.value.dutyDate,
                dutyUserId: editForm.value.userId,
                id: editForm.value.id,
                dutyUser: findItemUser(editForm.value.userId)
            }
            editData(tempData).then(res => {
                Message.success('编辑成功')
                visible.value = false
            })
        } else {
            const tempData = {
                dutyDate: editForm.value.dutyDate,
                dutyUserId: editForm.value.userId,
                // id: editForm.value.id,
                dutyUser: findItemUser(editForm.value.userId)
            }
            addData(tempData).then(res => {
                visible.value = false
                Message.success('添加成功')
            })
        }
        getTableData({
            pageNum: 1,
            pageSize: dateList.value.length,
            'params.beginTime': dateList.value[0],
            'params.endTime': dateList.value[dateList.value.length - 1],
        })
    } else {
        Message.error('请完整填写表单信息')
        return false
    }
};
// 删除
function handleDelete(val) {
    getInfo({ dutyDate: val.day }).then(res => {
        if (res?.rows[0]?.id) {
            deleteData(res.rows[0].id).then(res => {
                Message.success('删除成功')
                getTableData({
                    pageNum: 1,
                    pageSize: dateList.value.length,
                    'params.beginTime': dateList.value[0],
                    'params.endTime': dateList.value[dateList.value.length - 1],
                })
            })
        }
    })
}
const dateList = ref([])// 存放当前页所获取的所有日期
const calendar = ref();
const selectDate = (val) => {
    dateList.value.length = 0
    calendar.value.selectDate(val);
};
function handleMonthChange(date) {
    dateList.value.push(date)
}
const watchObj = computed(() => {
    return dateList.value[0]
})
watch(watchObj, (val) => {
    if (val) {
        const tempData = {
            pageNum: 1,
            pageSize: dateList.value.length,
            'params.beginTime': dateList.value[0],
            'params.endTime': dateList.value[dateList.value.length - 1],
        }
        getTableData(tempData)
    }
})
// 获取页面信息
const tableData = ref([])
const getTableData = (tempData) => {
    getInfo(tempData).then(res => {
        tableData.value = res.rows
    })
}
// 获取类型信息
const typeList = ref({
    deptList: [],
    userList: [],
    userLists: []
})
//  树选择器
const props = {
    expandTrigger: 'hover',
    label: "deptName",
    checkStrictly: true,
    value: "deptId",
}
function getTypeList() {
    getdept().then(res => {
        const temp = JSON.parse(JSON.stringify(res.data))
        typeList.value.deptList = handleTree(res.data, "deptId")
    })
    getUserData().then(res => {
        typeList.value.userLists = res.data
    })
}
const cas = ref()
function cascaderChange(data, id) {
    let nodes = cas.value.getCheckedNodes()
    getUser({ deptId: nodes[0].value }).then(res => {
        typeList.value.userList = res.rows
    })
}
const fetchData = () => {
    getTypeList()
}

onMounted(() => {
    fetchData()
});
</script>




<style scoped lang="less">
.wrapper {
    padding-top: 10px;
}

.duty-text {
    text-align: center;
    color: #939fb6;
    font-size: large;
}

.is-selected {
    color: #1989fa;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/534241.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flask项目如何在测试环境和生产环境部署上线

前言 最近在使用Flask框架&#xff0c;写一个小项目&#xff0c;在项目部署启动后&#xff0c;出现了以下这段提示&#xff0c;这段提示的意思是&#xff0c;该启动方式适用于开发环境中&#xff0c;生产环境要使用WSGI服务器。 WARNING: This is a development server. Do no…

Redis(Windows版本下载安装和使用)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

共享IP和独享IP如何选择,两者有何区别?

有跨境用户在选择共享IP和独享IP时会有疑问&#xff0c;不知道该如何进行选择&#xff0c;共享IP和独享IP各有其特点和应用场景&#xff0c;选择哪种方式主要取决于具体需求和预算。以下是对两者的详细比较&#xff1a; 首先两者的主要区别在于使用方式和安全性&#xff1a;共…

AI人工智能讲师简历大模型讲师叶梓大模型技术与应用培训提纲

叶梓&#xff0c;工学博士&#xff0c;高级工程师。现某大型上市企业资深技术专家。 2005年上海交通大学计算机专业博士毕业&#xff0c;在校期间的主研方向为数据挖掘、机器学习、人工智能。毕业后即进入软件行业从事信息化技术相关工作&#xff1b;负责或参与了多项国家级、省…

如何在 JavaScript 中创建自定义事件?

理解 JavaScript 中的事件 在深入研究自定义事件之前&#xff0c;我们首先了解 JavaScript 中事件的概念。事件是浏览器中发生的操作或事件&#xff0c;由用户交互&#xff08;如单击、鼠标移动或键盘输入&#xff09;或浏览器本身&#xff08;如页面加载、调整大小等&#xf…

超详细 - 一文说懂 C++ 继承(上)

目录 0 引言 1. 继承的概念 1.1 继承的本质 1.2 继承的作用 2. 继承的定义 2.1 继承的格式 2.2 继承的权限 2.3 默认继承 2.5 继承权限的使用 3. 继承的作用域 3.1 隐藏 4. 基类与派生类对象的赋值转换 4.1 切片 5. 派生类的默认成员函数 5.1 隐式调用 5.2 …

【软考---系统架构设计师】计算机网络章节

目录 一、TCP/IP协议族 &#xff08;1&#xff09;基本介绍 &#xff08;2&#xff09;TCP和UDP的区别 &#xff08;3&#xff09;DNS协议 &#xff08;4&#xff09;DHCP协议 二、网络规划与设计 &#xff08;1&#xff09;需求分析 &#xff08;2&#xff09;通信规范…

照片转漫画的软件有吗?分享4款热门的软件!

在数字化时代&#xff0c;我们总是追求新鲜、有趣、创意十足的方式来展现自我。其中&#xff0c;将普通照片转化为漫画风格的图像已成为许多年轻人的新宠。这种既能保留原照片中的人物特征&#xff0c;又能赋予其独特艺术气息的方式&#xff0c;让许多人趋之若鹜。那么&#xf…

头歌-机器学习 第16次实验 EM算法

第1关:极大似然估计 任务描述 本关任务:根据本节课所学知识完成本关所设置的选择题。 相关知识 为了完成本关任务,你需要掌握: 什么是极大似然估计; 极大似然估计的原理; 极大似然估计的计算方法。 什么是极大似然估计 没有接触过或者没有听过”极大似然估计“的同学…

[蓝桥杯 2018 国 C] 迷宫与陷阱

题目&#xff1a; 思路&#xff1a; 代码&#xff1a; #include <bits/stdc.h> using namespace std; const int N1e310; char g[N][N];//输入&#xff1a;图的数组 int vis[N][N]; /* 剪枝&#xff1a;记录magic的个数&#xff08;一个点经过两次&#xff0c;magic越大…

4.9号驱动

1. ARM裸机开发和Linux系统开发的异同 相同点&#xff1a;都是对硬件进行操作 不同点&#xff1a; 有无操作系统 是否具备多进程多线程开发 是否可以调用库函数 操作地址是否相同&#xff0c;arm操作物理地址&#xff0c;驱动操作虚拟地址 2. Linux操作系统的层次 应用层…

深度学习500问——Chapter07:生成对抗网络(GAN)(1)

文章目录 7.1 GAN基本概念 7.1.1 如何通俗理解GAN 7.1.2 GAN的形式化表示 7.1.3 GAN的目标函数是什么 7.1.4 GAN的目标函数和交叉熵有什么区别 7.1.5 GAN的Loss为什么降不下去 7.1.6 生成式模型、判别式模型的区别 7.1.7 什么是mode collapsing 7.1.8 如何解决mode collapsing …

【计算机毕业设计】就业信息管理系统——后附源码

&#x1f389;**欢迎来到琛哥的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 琛哥&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 琛哥在深度学习任务中展现出卓越的能力&a…

Java快速入门系列-9(Spring框架与Spring Boot —— 深度探索及实践指南)

第九章:Spring框架与Spring Boot —— 深度探索及实践指南 9.1 Spring框架概述9.2 Spring IoC容器9.3 Spring AOP9.4 Spring MVC9.5 Spring Data JPA/Hibernate9.6 Spring Boot快速入门与核心特性9.7 Spring Boot的自动配置与启动流程详解9.8 创建RESTful服务与数据库交互实践…

如何在Ubuntu系统使用docker部署DbGate容器并发布至公网可访问

文章目录 1. 安装Docker2. 使用Docker拉取DbGate镜像3. 创建并启动DbGate容器4. 本地连接测试5. 公网远程访问本地DbGate容器5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 本文主要介绍如何在Linux Ubuntu系统中使用Docker部署DbGate数据库管理工…

大数据基本名词

目录[-] 1.1. 1. Hadoop1.2. 2. Hive1.3. 3. Impala1.4. 4. Hbase1.5. 5.hadoop hive impala hbase关系1.6. 6. Spark1.7. 7. Flink1.8. 8. Spark 和 Flink 的应用场景 1. Hadoop 开源官网&#xff1a;https://hadoop.apache.org/ Hadoop是一个由Apache基金会所开发的分…

arXiv苹果公司新论文“Self-Play”方法训练车辆道路merge的策略

arXiv苹果公司新论文“Self-Play”方法训练车辆道路merge的策略 附赠自动驾驶学习资料和量产经验&#xff1a;链接 苹果于2020年1月28日上传arXiv新论文“Towards Learning Multi-agent Negotiations via Self-Play“。 摘要&#xff1a; 做出复杂、鲁棒和安全的串行决策是智能…

0169. 多数元素

Problem: 169. 多数元素 文章目录 思路解题方法复杂度Code 思路 利用哈希表计数&#xff0c;遍历一遍数组此时时间复杂度为 O ( n ) O(n) O(n)&#xff0c;空间复杂度为 O ( n ) O(n) O(n)。 参考K神学会摩尔投票法 这个方法思想很简单&#xff0c;就是模拟投票&#xff0c;且…

嵌入式热门发展方向有哪些?

嵌入式热门发展方向有哪些? 现在越来越多的计算机、电子、通信、自动化等相关专业跨行学习嵌入式&#xff0c;嵌入式开发作为未来职业发展的方向&#xff0c;不论从薪资待遇还是发展前景来看&#xff0c;都非常不错。 在嵌入式领域&#xff0c;有多个热门发展方向&#xff0…

JVM常用参数一

jvm启动参数 JVM&#xff08;Java虚拟机&#xff09;的启动参数是在启动JVM时可以设置的一些命令行参数。这些参数用于指定JVM的运行环境、内存分配、垃圾回收器以及其他选项。以下是一些常见的JVM启动参数&#xff1a; -Xms&#xff1a;设置JVM的初始堆大小。 -Xmx&#xff1…