• vue-待办日历和Table


    基于Element-UI日历组件的待办事项例子

    想实现一个日历提醒待办事项的功能,主要实现的功能是:

    • 日历上展示是否有待办的事情,如果有则为红色对勾,如果全部是已完成则用绿色对勾,没有事项时候则没有任何标识
    • 日历组件上侧有展开待办的列表功能(以Table形式展现)
      主要涉及的组件有
    • todoCellCheck.vue(用来检查每个日期是否有待办且是否全部完成)
    • todoItem.vue(点击日期时,弹出事项的列表)
    • todoItemTable.vue(通过折叠功能,展示Table形式的待办)
      测试数据中,Mock返回待办事项的数组,例如以下数据:
    /**
     * abstract:概要
     * detail:明细
     * status:
     * 0 已办
     * 1 待办
     * 999 最大状态
     */
    const todoThings = [
      {
        date: "2020-04-14",
        abstract: "王小虎1",
        detail: "上海市普陀区金沙江路 1518 弄",
        status: 1
      },
      {
        date: "2020-04-14",
        abstract: "王小虎2",
        detail: "上海市普陀区金沙江路 1518 弄",
        status: 0
      }]
    

    业务相关的内容在src下新建bear,配置相关的modules扫描,并且加入到store中src>bear>index.js如下:

    const modulesFiles = require.context("./modules", true, /.js$/);
    
    const bearmodules = modulesFiles.keys().reduce((modules, modulePath) => {
      const moduleName = modulePath.replace(/^./(.*).w+$/, "$1");
      const value = modulesFiles(modulePath);
      modules[moduleName] = value.default;
      return modules;
    }, {});
    
    export default bearmodules;
    
    

    在store的index.js中导入bearmodules。业务代码的modules在src>bear>modules>todoThings.js如下:

    import { getTodoThingsByDate } from "@/api/todoThings/todoThings";
    
    const actions = {
      getTodoThingsByDate(context, { beginDate, endDate }) {
        return new Promise((resolve, reject) => {
          getTodoThingsByDate(beginDate, endDate)
            .then(response => {
              const { data } = response;
              const resp = { code: 200, message: "Success", data: data };
              resolve(resp);
            })
            .catch(error => {
              reject(error);
            });
        });
      }
    };
    
    export default {
      namespaced: true,
      actions
    };
    
    

    在src>views下新建todothings目录,待办日历的index.vue如下:

    <template>
      <el-row>
        <el-row>
          <el-button type="primary" :icon="collapseListIcon" @click="collapseList">
            {{ collapseListTitel }}
          </el-button>
        </el-row>
        <el-row>
          <el-col :span="calendarSpan">
            <div class="grid-content bg-purple">
              <el-calendar v-model="calendarValue">
                <template v-slot:dateCell="{ date, data }">
                  <todoItem
                    v-if="data.isSelected"
                    :itemsDataGroupByDate="todoDataGroupByDate"
                    :cellDate="data.day"
                  >
                  </todoItem>
                  <!-- 初始化标记是否有事情要办 -->
                  <todoCellCheck
                    :itemsDataGroupByDate="todoDataGroupByDate"
                    :cellDate="data.day"
                  ></todoCellCheck>
                  <p :class="data.isSelected ? 'is-selected' : ''">
                    {{
                      data.day
                        .split("-")
                        .slice(1)
                        .join("-")
                    }}
                  </p>
                </template>
              </el-calendar>
            </div>
          </el-col>
          <el-col :span="todoItemSpan" v-if="isCollapseList">
            <todoItemTable :tableData="todoItemThings"></todoItemTable>
          </el-col>
        </el-row>
      </el-row>
    </template>
    
    <script>
    import todoItem from "./components/todoItem";
    import todoItemTable from "./components/todoItemTable";
    import todoCellCheck from "./components/todoCellCheck";
    import { jsonArraysGroupByValue } from "@/utils/jsonUtils.js";
    import { prevMonthFirstDate, nextMonthLastDate } from "@/utils/date";
    
    export default {
      created() {
        this.initTodoThings();
      },
    
      data() {
        return {
          /**
           * calendarSpan 日历宽度
           * todoItemSpan 右侧列表宽度
           * isCollapseList 右侧折叠
           * cellDate 选中单元格的日期
           * cellData 选中单元格的数据
           * cellItemThings 选中单元格弹出层的待办事项
           * todoItemThings 当前月及前后各一月的事项
           * calendarValue 日历当前月
           * ---------------
           * todoDataGroupByDate 按日期分组的待办事项
           * ---------------
           *
           */
          calendarSpan: 12,
          todoItemSpan: 12,
          isCollapseList: true,
          cellDate: null,
          cellData: null,
          collapseListTitel: "收起列表",
          collapseListIcon: "el-icon-arrow-left",
          cellItemThings: null,
          // calendarData: null,
          calendarValue: new Date(),
          todoItemThings: null,
          todoDataGroupByDate: null,
          contextmenuVisible: false,
          top: 0,
          left: 0,
          editFormVisible: false
        };
      },
      components: { todoItem, todoItemTable, todoCellCheck },
      watch: {
        calendarValue() {
          this.initTodoThings();
        }
      },
      methods: {
        //查询选中日期及前后各一个月的todo
        initTodoThings() {
          const beginDate = prevMonthFirstDate(this.calendarValue);
          const endDate = nextMonthLastDate(this.calendarValue);
          this.$store
            .dispatch("todoThings/getTodoThingsByDate", {
              beginDate: beginDate,
              endDate: endDate
            })
            .then(response => {
              if (response.code === 200) {
                this.todoItemThings = response.data;
                this.todoDataGroupByDate = jsonArraysGroupByValue(
                  this.todoItemThings,
                  "date"
                );
              }
            });
        },
        collapseList() {
          if (this.isCollapseList) {
            this.calendarSpan = 24;
            this.todoItemSpan = 0;
          } else {
            this.calendarSpan = 12;
            this.todoItemSpan = 12;
            this.cellDate = null;
            this.cellData = null;
          }
          this.isCollapseList = !this.isCollapseList;
          this.collapseListTitel = !this.isCollapseList ? "展开列表" : "收起列表";
          this.collapseListIcon = !this.isCollapseList
            ? "el-icon-arrow-right el-icon--right"
            : "el-icon-arrow-left";
        }
      }
    };
    </script>
    
    <style lang="scss" scoped>
    .is-selected {
      color: #1989fa;
    }
    </style>
    

    日历组件在初始化时查询相应的待办,并且将所有待办数据按日期进行分组,同时布局方面默认展开右侧的Table

    作为检查日历中日期是否有待办,使用了todoCellCheck.vue组件,思路是先将所有待办事项按日期分组,之后和加载的日期想对比,根据分组内的status属性求和作为结果,status和为0则说明所有事项均以完成。代码如下:

    <script>
    export default {
      name: "todoCellCheck",
      functional: true,
      props: {
        itemsDataGroupByDate: {
          type: Object,
          default: null
        },
        cellDate: {
          type: String,
          default: ""
        }
      },
      render(h, context) {
        const { itemsDataGroupByDate, cellDate } = context.props;
        const vnodes = [];
        let status = 999;
        if (itemsDataGroupByDate !== null) {
          Object.keys(itemsDataGroupByDate).forEach(function(category) {
            if (category === cellDate) {
              status = itemsDataGroupByDate[category].reduce(
                (prev, currentValue) => {
                  return prev + currentValue.status;
                },
                0
              );
              status === 0 && status !== 999
                ? // ? vnodes.push(<svg-icon icon-class="greenmark" />)
                  vnodes.push("✔️")
                : vnodes.push(<svg-icon icon-class="redmark" />);
            }
          });
        }
        return vnodes;
      }
    };
    </script>
    
    

    todoItem.vue组件绑定实现当点击日期时,弹出一个页面提示当前日期的待办事项。代码如下:

    <template>
      <div class="todocell">
        <slot name="todoItems" :itemThings="cellItemThings"></slot>
        <el-popover placement="right" width="800" trigger="click" v-model="visible">
          <el-table :data="cellItemThings" :row-class-name="tableRowClassName">
            <el-table-column
              width="150"
              property="date"
              label="日期"
            ></el-table-column>
            <el-table-column
              width="100"
              property="abstract"
              label="概要"
            ></el-table-column>
            <el-table-column
              width="300"
              property="detail"
              label="明细"
            ></el-table-column>
    
            <el-table-column label="状态" width="100">
              <template slot-scope="scope">
                <i class="el-icon-time"></i>
                <span style="margin-left: 10px">{{
                  scope.row.status === 0 ? "已完成" : "待完成"
                }}</span>
              </template>
            </el-table-column>
          </el-table>
        </el-popover>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        itemsDataGroupByDate: {
          type: Object,
          default: null
        },
        cellDate: {
          type: String,
          default: ""
        }
      },
      created() {
        this.initCellItemThings();
      },
      data() {
        return {
          visible: false,
          cellItemThings: null
        };
      },
      methods: {
        initCellItemThings() {
          if (this.itemsDataGroupByDate !== null) {
            this.cellItemThings = this.itemsDataGroupByDate[this.cellDate];
            if (
              this.cellItemThings !== null &&
              typeof this.cellItemThings !== "undefined"
            ) {
              this.visible = true;
            }
          }
        },
        tableRowClassName({ row }) {
          if (row.status === 0) {
            return "success-row";
          } else {
            return "warning-row";
          }
        }
      }
    };
    </script>
    <style scoped>
    .todocell {
      color: #1989fa;
    }
    .el-table .warning-row {
      background: oldlace;
    }
    
    .el-table .success-row {
      background: #f0f9eb;
    }
    </style>
    
    

    目前展示效果如下截图

    样式比较难弄,准备修改成vue-element-admin的Table样式

  • 相关阅读:
    JAVA,模拟HTTP登录(略有修改) ----转载自http://zhoujingxian.iteye.com/blog/439738
    java的mysql初探
    java的IO流初探
    java自己写的简单聊天工具SimpleQQ感悟
    java多线程初探
    java事件监听机制2
    JAVA事件监听机制的实现
    iOS (两行代码实现)浮点数保留两位小数且末尾0不展示
    iOS 13.4 & Xcode 11.4 采坑小记(重写系统get)
    Masonry 使用小记(动态宽度依赖)
  • 原文地址:https://www.cnblogs.com/GYoungBean/p/12802222.html
Copyright © 2020-2023  润新知