在vue中element ui 结合frappe-gantt实现一个简单的甘特图功能

这篇具有很好参考价值的文章主要介绍了在vue中element ui 结合frappe-gantt实现一个简单的甘特图功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  1. 在vue中创建甘特图步骤请参考: https://editor.csdn.net/md/?articleId=130145782

2. 结合element ui 实现甘特图功能

实现效果:
elementui甘特图,vue.js,javascript,ui

2.1 下载element ui

因为我是在vue3中,所以下载element-plus 执行 npm i element-plus --save
main.js 里引入element ui

import { createApp } from 'vue'

import ElementPlus from 'element-plus';//1.引入组件
import 'element-plus/theme-chalk/index.css';//2.引入CSS
import locale from 'element-plus/lib/locale/lang/zh-cn';
import App from './App.vue';

createApp(App).use(ElementPlus, { locale }).mount('#app')

2.2. 创建Gantt.vue组件

<template>
  <div class="gantt-container">
    <el-row>
      <el-col :span="8">
        <el-table
          :data="tasks"
          stripe
          style="width: 100%"
          row-key="id"
          border
          lazy
          :load="load"
          :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        >
          <el-table-column prop="name" width="160" label="任务名称" show-overflow-tooltip />
          <el-table-column prop="start" width="140" label="开始日期" show-overflow-tooltip />
          <el-table-column prop="end" width="140" label="结束日期" show-overflow-tooltip />
          <el-table-column prop="date" width="140" label="持续时间" show-overflow-tooltip />
          <el-table-column prop="task" width="80" label="完成" show-overflow-tooltip />
          <el-table-column label="Operations" width="300">
            <template #default="scope">
              <el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
              <el-button
                size="small"
                type="danger"
                @click="handleAddChild(scope.$index, scope.row)"
              >添加子任务</el-button>
              <el-button
                v-if="scope.$index !== 0"
                size="small"
                type="danger"
                @click="handlemove(scope.$index, scope.row)"
              >上移一行</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-col>
      <el-col :span="16">
        <div class="gantt-target"></div>
      </el-col>
    </el-row>
    <el-button type="primary" @click="handleADD">新增</el-button>
  </div>
</template>

<script>
import { reactive, toRefs, onMounted } from "vue";
import Gantt from "../assets/dist/frappe-gantt";
export default {
  setup() {
    const vueConfig = reactive({
      tasks: [ // 表格数据
        {
          start: "2023-04-01",
          end: "2023-04-08",
          name: "测试任务1",
          id: "1",
          progress: 26,
          task: "50%",
          date: 3,
          children: []
        },
        {
          start: "2023-04-03",
          end: "2023-04-06",
          name: "测试任务2",
          id: "2",
          progress: 0,
          task: "50%",
          date: 3,
          children: []
          // dependencies: '1'
        },
        {
          start: "2023-04-04",
          end: "2023-04-08",
          name: "测试任务3",
          id: "3",
          progress: 0,
          task: "50%",
          date: 3,
          children: []
          // dependencies: '1'
        },
        {
          start: "2023-04-08",
          end: "2023-04-09",
          name: "测试任务4",
          id: "4",
          progress: 0,
          task: "50%",
          date: 3,
          children: []
          // dependencies: '2'
        },
        {
          start: "2023-04-08",
          end: "2023-04-10",
          name: "测试任务5",
          id: "5",
          progress: 50,
          task: "50%",
          date: 3,
          children: []
          // dependencies: '2'
        }
      ],
      gantt: null,
      ganttData: null, // 甘特图数据
    });
    let handleADD = () => {
      console.log("新增按钮点击");
      vueConfig.tasks.push({
        start: "2023-04-08",
        end: "2023-04-10",
        name: "测试任务6",
        id: "6",
        progress: 0,
        task: "50%",
        date: 3
        // dependencies: '2'
      });
      createG();
    };
    let handleEdit = item => {
      console.log("编辑按钮点击");
      vueConfig.tasks.forEach(element => {
        if (element.id === item.id) {
          element.start = "2022-04-02";
          element.end = "2022-04-07";
          element.date = 5;
          element.task = "60%";
        }
      });
      createG();
    };
    let handleAddChild = (index, item) => {
      console.log("添加子任务按钮点击");
      console.log(index, item);
      vueConfig.tasks.forEach(element => {
        if (element.id === item.id) {
          element.children.push({
            start: "2022-04-01",
            end: "2022-04-08",
            name: "测试任务子任务1",
            id: "8",
            progress: 0,
            task: "50%",
            date: 3,
            dependencies: "1"
          });
        }
      });
      createG();
    };
    let handlemove = (index, item) => {
      console.log("上移一行按钮点击");
      const tempItem = vueConfig.tasks.splice(index, 1);
      vueConfig.tasks.splice(index - 1, 0, tempItem[0]);
      createG();
    };

    let formatGantt = () => {
      console.log("执行formatGantt");
      let result = [];
      let obj = {
        start: "",
        end: "",
        name: "",
        id: "",
        progress: 0,
        task: "",
        date: 0,
        children: []
      };
      vueConfig.tasks.forEach(element => {
        if (element.children.length === 0) {
          console.log(element);
          result.push(element);
        } else {
          obj.start = element.start;
          obj.end = element.end;
          obj.name = element.name;
          obj.id = element.id;
          obj.progress = element.progress;
          obj.task = element.task;
          obj.date = element.date;
          result.push(obj);
          result = result.concat(element.children);
        }
      });
      vueConfig.ganttData = result;
    };
    let createG = () => {
      formatGantt();
      const gantt = new Gantt(".gantt-target", vueConfig.ganttData, {
        on_click: function(task) {
          console.log("双击操作", task);
        },
        on_date_change: function(task, start, end) {
          vueConfig.tasks.forEach(element => {
            if (element.id === task.id) {
              element.start = start;
              element.end = end;
              element.data = end - start;
            }
          });
        },
        on_progress_change: function(task, progress) {
          console.log(task, progress);
        },
        on_view_change: function(mode) {
          console.log(mode);
        },
        // view_mode: 'Day',
        language: "zh",
        header_height: 70,
        column_width: 90,
        step: 24,
        view_modes: ["Quarter Day", "Half Day", "Day", "Week", "Month"],
        bar_height: 62,
        bar_corner_radius: 5, // bar 的圆角度
        arrow_curve: 20, //连接子任务的线条曲线度
        padding: 18,
        view_mode: "Day", // header的日期类型
        date_format: "YYYY-MM-DD", // 日期格式
        custom_popup_html: function(task) {
          return `
          <div class="details-container">
            <h5>${task.name}</h5>
            <p>Expected to finish by ${task.end}</p>
            <p>${task.progress}% completed!</p>
          </div>
          `;
        }
      });
    };
    onMounted(() => {
      createG();
    });
    return {
      ...toRefs(vueConfig),
      handleADD,
      createG,
      handleEdit,
      handleAddChild,
      handlemove,
      formatGantt,
    };
  }
};
</script>

<style lang="scss" scoped>
@import "../assets/dist/frappe-gantt.css";

.gantt-container {
  background-color: transparent;
  width: 100%;
  overflow: hidden;
  margin-left: -1px;
}


::v-deep .el-table .el-table__cell {
  height: 80px;
}

::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td {
  background: rgb(245, 245, 245);
}

::v-deep .el-table--enable-row-hover .el-table__body tr:hover > td {
  background: rgb(245, 245, 245);
}

.gantt .bar {
  background-color: #007bff;
  height: 20px;
}


.el-button--text {
  margin-right: 15px;
}
.el-select {
  width: 300px;
}
.el-input {
  width: 300px;
}
.dialog-footer button:first-child {
  margin-right: 10px;
}
</style>

这样就可以实现一个简单的功能了。文章来源地址https://www.toymoban.com/news/detail-519418.html

到了这里,关于在vue中element ui 结合frappe-gantt实现一个简单的甘特图功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • vue结合element-ui实现(按钮控制)动态增加减少input框功能。

    vue结合element-ui实现(按钮控制)动态增加减少input框功能。

    一、template部分 二、script部分 三、效果展示 这是初始页面  这是点击添加 这是删除的     四、详细说明 v-for=\\\"(item,index)in array\\\" :key = \\\"index\\\" 这个是重点!!! ! 通俗点将,就是用一个div(盒子)将input输入框包括起来,然后在div中使用 v-for=\\\"(item,index)in array\\\" :key = \\\"ind

    2024年02月12日
    浏览(21)
  • Vue搜索组件,显示热门、近期搜索(结合element ui)

    Vue搜索组件,显示热门、近期搜索(结合element ui)

    🚀 注重版权,转载请注明原作者和原文链接 🥭 作者:全栈小袁 🍎 原创个人开源博客项目(目前V3.0版本):https://github.com/yuanprogrammer/xiaoyuanboke 🍉 开源项目觉得还行的话点点star,有什么需要完善或者点子欢迎提issue 也是好久没有发文章了,之前忙着秋招校招春招,入职后一

    2024年02月16日
    浏览(17)
  • Element UI结合vue-cropper打造图片裁剪上传组件

    Element UI结合vue-cropper打造图片裁剪上传组件

    props: { //图片裁切配置 options: { type: Object, default: function() { return { autoCrop: true, //是否默认生成截图框 autoCropWidth: 180, //默认生成截图框宽度 autoCropHeight: 180, //默认生成截图框高度 fixedBox: false, //是否固定截图框大小 不允许改变 previewsCircle: true, //预览图是否是原圆形 title: ‘修改

    2024年04月10日
    浏览(18)
  • Vue中使用element-ui 给按钮绑定一个单击事件,实现点击按钮就弹出一个dialog对话框

    Vue中使用element-ui 给按钮绑定一个单击事件,实现点击按钮就弹出一个dialog对话框

    1.需求描述 想要实现点击一个按钮就弹出一个对话框,在对话框中可输入数据进行提交,在点击取消时对话框关闭 2.功能实现 1.创建按钮 在element中把找到按钮的代码放到div里 2.创建对话框 在element中找到dialog对话框对应的代码,把代码粘贴到对应的位置 3.对话框与按钮的绑定

    2024年01月18日
    浏览(54)
  • Element UI结合vue-cropper打造图片裁剪上传组件,Android开发面试书籍

    Element UI结合vue-cropper打造图片裁剪上传组件,Android开发面试书籍

    left: 0; color: #ccc; font-size: 8px; right: 0; } } } ::v-deep .avatar-uploader .el-upload–text { border: 1px dashed #d9d9d9; border-radius: 6px; margin-right: 20px; cursor: pointer; position: relative; overflow: hidden; } ::v-deep .avatar-uploader .el-upload:hover { border-color: #409eff; } ::v-deep .avatar-uploader-icon { font-size: 22px; color: #ccc; wi

    2024年04月13日
    浏览(14)
  • 【vue】创建第一个vue+element ui项目

    【vue】创建第一个vue+element ui项目

    1. 前言 在之前的文章中已经搭建了vue开发环境,并创建好了vue项目,接下来开始创建第一个vue+element项目 之前的文章请移步:1. 使用vscode运行Vue项目 2. 在vscode中创建vue项目 Element-Ui与Vue关系: Element-Ui是基于Vue封装的组件库,主要作用是简化了常用组件的封装。 简单来说Vu

    2023年04月08日
    浏览(13)
  • 基于Vue2.0仿Element UI的el-tooltip实现一个气泡框组件,支持多数据类型的显示和内容为空时不显示气泡框

    基于Vue2.0仿Element UI的el-tooltip实现一个气泡框组件,支持多数据类型的显示和内容为空时不显示气泡框

    场景:因为有个需求就是鼠标经过可多选的 el-select 选择器时,需要有个气泡框显示已选的内容,其实 el-tooltip 气泡框可以满足需求,就是用 el-tooltip 气泡框来包裹 el-select 选择器,但是当选择器一个也没选中,即内容为空时不应该也显示气泡框,有点影响美观。应该就是若内

    2024年02月13日
    浏览(16)
  • vue 做一个文本展示 点击文本弹出element ui的时间选择器 但不会出现element ui时间组件的那个输入框

    vue 做一个文本展示 点击文本弹出element ui的时间选择器 但不会出现element ui时间组件的那个输入框

    我们先来创建一个vue2项目 引入element ui 然后 找到一个组件 这样写 这样 我们就写出了一个基本的element ui时间选择组件 但这显然不是我们要的效果 这里我们给时间控件了一个class pickerTime 用它来控制样式 我们css部分代码这样写一下 这样 我们的组件就看不到了 先别急 然后

    2024年02月07日
    浏览(15)
  • Vue3 + Element-UI 搭建一个后台管理系统框架模板

    本文将介绍如何基于Vue3和element-ui搭建一个后台管理系统框架模板。我们将详细讲解代码流程,并提供详细的说明。 Vue3 Element-ui Axios 本文假设读者已经熟悉Vue3和Element-ui的基本使用方法,并且对Axios有一定的了解。 步骤1:创建Vue3项目 我们可以使用Vue CLI来创建一个Vue3项目,

    2023年04月26日
    浏览(25)
  • element UI table横向树结合checkbox进行多选,实现各个节点的[全选,半选,不选]状态附带模拟数据

    element UI table横向树结合checkbox进行多选,实现各个节点的[全选,半选,不选]状态附带模拟数据

    步骤一、后端返回tree格式数据,先结合element-ui的table的数据格式要求,将tree转换成table数据,进行行列的合并。 步骤二、拿到数据,递归遍历后将选中数据的id保存,进行回显操作。 步骤三、将每个checkbox进行绑定方法,此方法将作为分叉,如果当前checkbox属于父亲节点,判

    2024年02月08日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包