vue项目中使用element-ui中的el-calendar日历制作考勤

  • Post author:
  • Post category:vue


最近做到一个项目,项目中涉及到人员考勤记录,做了好几版,总感觉页面太过于复杂,最后想到要用日历进行做一个简单又明了的个人考勤记录。文中使用了el-calenda方法,点击名字搜索特定的人,来调用后端接口渲染页面。



搜索功能应该就不用过多的写了吧,直接讲一下日历这一块的代码吧

<div>
  <el-calendar v-model="calendarValue">
     <template slot="dateCell" slot-scope="{ data }">
        <div class="date-cell">
           <div class="calendar-day">
              {{ data.day.split("-").slice(2).join("-") }}
           </div>
         <div
           v-for="(item, index) in formatSchedule(data)"
           :key="index"
           class="calendarValue"
            :class=" item.result != '正常' ? 'text-danger' : 'text-primary' "
            @click="chooseDay(item)"
          >
             <div class="text">
                <span>上班:{{ item.morning }}</span>
             </div>
             <div class="text">
               <span>下班:{{ item.afternoon }}</span>
             </div>
        </div>
      </div>
    </template>
  </el-calendar>
</div>

上面是渲染的标签写法,下面是JS部分,首先你要定义data数据

 data() {
    return {
      dataForm: [],
      calendarValue: "", // 绑定数据
      departmentName: [], // 姓名
      tradeData: {
        schedule: [],
      }, // 本月考勤情况
      text: "",
      listLoading: false,
      id: "",
      total: 0,
      searchForm: {
        userName: "",
        currentPage: 1,
        pageSize: 10,
      },
    };
  },

然后是computed计算属性

computed: {
    //将返回数据里的时间与日历控件里的时间匹配,将数据回显在对应的位置上
    //数据的时间格式: riqi:"2021-06-05" --- yyyy-MM-dd;
    //如果后端返回的时间不是yyyy-MM-dd,要转格式再匹配
    formatSchedule() {
      return (data) => {
        return this.tradeData.schedule.filter((ele) => {
          let time = ele.riqi;
          return time == data.day;
        });
      };
    },
  },

接着是methods方法,最主要的就是这一步,点击某一天进行提示

  // 点击某一天进行提示
    chooseDay(data) {
      if (data.result == "正常") {
        this.$message.success("该员工今日考勤一切正常");
      } else {
        this.$message.warning("该员工今日存在" + data.result + "现象");
      }

这个组件可以通过css来改变他的基本样式,有很多样式都是通过css来改变的,可以利用开发者检查工具来点点看看,哪些类名可以改变啥

我用到的大概就这些个方法:

// 只显示本月日期
::v-deep .el-calendar-table:not(.is-range) td.next {
  display: none;
}
::v-deep .el-calendar-table:not(.is-range) td.prev {
  visibility: hidden;
}

// 自定义文字居中显示
.calendarValue {
  text-align: center;
}
// 文本超出省略号显示
.text {
  width: 100%;
  // display: inline-block;
  white-space: nowrap; 
  overflow: hidden;
  text-overflow:ellipsis;
}

以下是完整代码

<template>
  <transition>
    <div>
      <div>
        <el-page-header @back="goBack" :content="text" />
      </div>
      <div>
        <el-form :model="searchForm" style="margin: 20px">
          <el-col>
            <el-form-item
              label="人员姓名:"
              prop="userName"
              style="width: 80%"
            >
              <el-select v-model="value" placeholder="请选择">
                 <!-- 自己做一个人员搜索功能就ok了,我的就不进行展示了 -->
              </el-select>
            </el-form-item>
          </el-col>
          <el-button type="primary" @click="search" size="mini">
            <i class="el-icon-search"></i>
            查询
          </el-button>
        </el-form>
        <div>
          <el-calendar v-model="calendarValue">
            <template slot="dateCell" slot-scope="{ data }">
              <div class="date-cell">
                <div class="calendar-day">
                  {{ data.day.split("-").slice(2).join("-") }}
                </div>
                <div
                  v-for="(item, index) in formatSchedule(data)"
                  :key="index"
                  class="calendarValue"
                  :class="
                    item.result != '正常' ? 'text-danger' : 'text-primary'
                  "
                  @click="chooseDay(item)"
                >
                  <div class="text">
                    <span>上班:{{ item.morning }}</span>
                  </div>
                  <div class="text">
                    <span>下班:{{ item.afternoon }}</span>
                  </div>
                </div>
              </div>
            </template>
          </el-calendar>
        </div
      </div>
    </div>
  </transition>
</template>

<script>
此处引入接口,来进行人员查询,获取考勤时间

export default {
  data() {
    return {
      dataForm: [],
      calendarValue: "", // 绑定数据
      departmentName: [], // 姓名
      tradeData: {
        schedule: [],
      }, // 本月考勤情况
      text: "",
      listLoading: false,
      id: "",
      total: 0,
      searchForm: {
        userName: "",
        currentPage: 1,
        pageSize: 10,
      },
    };
  },
  computed: {
    //将返回数据里的时间与日历控件里的时间匹配,将数据回显在对应的位置上
    //数据的时间格式: riqi:"2021-06-05" --- yyyy-MM-dd;
    //如果后端返回的时间不是yyyy-MM-dd,要转格式再匹配
    formatSchedule() {
      return (data) => {
        return this.tradeData.schedule.filter((ele) => {
          let time = ele.riqi;
          return time == data.day;
        });
      };
    },
  },
  methods: {
    async init(type, val) {
      this.listLoading = true;
      this.text = "考勤人员" + "详情";
      this.calendarValue = val.attendantMonth; // 初次打开不显示数据
      this.id = val.id;
      const { data: res } = await getTeamUserList({
        id: val.id,
      });
      // 将名字重处理
      this.departmentName = res.list;
      var result = [];
      var obj = {};
      for (var i = 0; i < this.departmentName.length; i++) {
        if (!obj[this.departmentName[i].userName]) {
          result.push(this.departmentName[i]);
          obj[this.departmentName[i].userName] = true;
        }
      }
      this.departmentName = result;
      this.listLoading = false;
    },
    goBack() {
      this.$emit("close", close);
    },
    // 搜索
    async search() {
      let kfr = {
        userName: this.searchForm.userName,
        currentPage: this.searchForm.currentPage,
        pageSize: this.searchForm.pageSize,
        id: this.id,
      };
      if (kfr.userName != "") {
        const { data: res } = await getTeamUserList(kfr);
        this.tradeData.schedule = res.list;
      } else {
        this.$message.error("请选择需要查询人的姓名");
      }
    },

    // 点击某一天进行提示
    chooseDay(data) {
      if (data.result == "正常") {
        this.$message.success("该员工今日考勤一切正常");
      } else {
        this.$message.warning("该员工今日存在" + data.result + "现象");
      }
    },
  },
};
</script>

<style lang="scss" scoped>
::v-deep .el-calendar-table thead th {
  border: 1px solid rgba(235, 238, 245);
  font-weight: 500;
  text-align: center;
}

// 取消右上角自带的按钮
::v-deep .el-calendar__header {
  .el-calendar__button-group {
    display: none;
  }
}

// 只显示本月日期
::v-deep .el-calendar-table:not(.is-range) td.next {
  display: none;
}
::v-deep .el-calendar-table:not(.is-range) td.prev {
  visibility: hidden;
}

// 自定义文字居中显示
.calendarValue {
  text-align: center;
}
// 文本超出省略号显示
.text {
  width: 100%;
  // display: inline-block;
  white-space: nowrap; 
  overflow: hidden;
  text-overflow:ellipsis;
}
</style>

有必要写一下后端数据格式

list: [{teamName: "*****", afternoon: "18:00", result: "正常", teamId: "16554837369*****",…},…]
0: {teamName: "*****", afternoon: "18:00", result: "正常", teamId: "1********8113",…}
  afternoon: "18:00"  // 下午打卡时间
  morning: "08:00"  // 上午打卡时间
  result: "正常"  // 今日打卡是否正常
  riqi: "2023-05-01"  // 日期
  teamId: "*****"  // 唯一标识
  teamName: "****"  // 班组
  userId: "****"  // 别考核人员id
  userName: "***"  // 被考核人姓名
1: {teamName: "*****", afternoon: "18:00", result: "正常", teamId: "**********13",…}
2: {teamName: "*****", afternoon: "18:00", result: "正常", teamId: "16*************",…}.....

第一次写博客,可能写的有点乱,大家将就着看,有啥不懂不明白的欢迎留言交流



版权声明:本文为Dreams_are_horse原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。