0
点赞
收藏
分享

微信扫一扫

vue3+dhtmlx-gantt的简单demo

有态度的萌狮子 2022-05-06 阅读 52

main.js

import { createApp } from "vue";
import App from "./App.vue";
import { gantt } from "dhtmlx-gantt";
import "dhtmlx-gantt/codebase/dhtmlxgantt.css"

const app = createApp(App);

app.config.globalProperties.$gantt = gantt;
app.mount("#app");

gantt.vue

<template>
  <div class="hello">
    <div ref="gantt" style="height: 500px"></div>
  </div>
</template>

<script setup>
import {
  getCurrentInstance,
  onMounted,
  defineEmits,
  defineExpose,
  defineProps,
} from "vue";
const props = defineProps({
  tasks: {
    type: Object,
    default: () => ({
      data: [],
      tasks: [],
    }),
  },
});
const { proxy } = getCurrentInstance();
const emit = defineEmits(["link-updated", "task-updated", "task-selected"]);

onMounted(() => {
  proxy.$gantt.config.xml_date = "%Y-%m-%d";
  proxy.$gantt.config.columns = [ //左侧列
    { name: "text", label: "任务名称", tree: true, width: 200 },
    { name: "start_date", label: "开始时间", align: "center" },
    { name: "end_date", label: "结束时间", align: "center" },
    { name: "duration", label: "工期", align: "center" },
    { name: "add", label: "" },
  ];
  proxy.$gantt.config.sort = true;//表格排序
  proxy.$gantt.config.scale_unit = "week";
  proxy.$gantt.config.date_scale = "%M"; //表头日期格式
  proxy.$gantt.config.scales = [{ unit: "week", step: 1, format: "%M,%Y" }];
  proxy.$gantt.config.subscales = [
    //二级表头配置,二级表头在表格中是上排
    {
      unit: "month", //表头时间单位
      step: 1,
      date: "%M,%Y",
    },
  ];
  proxy.$gantt.config.scale_height = 60; //表头高度
  proxy.$gantt.config.min_column_width = 40; //表格最小列宽
  proxy.$gantt.templates.task_text = (start, end, task) => {
    return `自定义格式:${task.text}`;
  };
  proxy.$gantt.i18n.setLocale({
    date: {
      month_full: [
        "一月",
        "二月",
        "三月",
        "四月",
        "五月",
        "六月",
        "七月",
        "八月",
        "九月",
        "十月",
        "十一月",
        "十二月",
      ],
      month_short: [
        "1月",
        "2月",
        "3月",
        "4月",
        "5月",
        "6月",
        "7月",
        "8月",
        "9月",
        "10月",
        "11月",
        "12月",
      ],
      day_full: [
        "星期天",
        "星期一",
        "星期二",
        "星期三",
        "星期三",
        "星期五",
        "星期六",
      ],
      day_short: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
    },
    labels: {
      new_task: "新任务",
      icon_save: "保存",
      icon_cancel: "取消",
      icon_details: "细节",
      icon_edit: "编辑",
      icon_delete: "删除",
      gantt_save_btn: "New Label",
      gantt_cancel_btn: "New Label",
      gantt_delete_btn: "New Label",
      confirm_closing: "", // Your changes will be lost, are you sure?
      confirm_deleting: "Task will be deleted permanently, are you sure?",
      section_description: "描述",
      section_time: "时间区段",
      section_type: "类型",

      /* grid columns */
      column_wbs: "WBS",
      column_text: "任务名称",
      column_start_date: "开始时间",
      column_duration: "时长",
      column_add: "",

      /* link confirmation */
      link: "Link",
      confirm_link_deleting: "将被删除",
      link_start: " (start)",
      link_end: " (end)",

      type_task: "任务",
      type_project: "项目",
      type_milestone: "Milestone",

      minutes: "分钟",
      hours: "小时",
      days: "天",
      weeks: "周",
      months: "月",
      years: "年",

      /* message popup */
      message_ok: "确定",
      message_cancel: "取消",

      /* constraints */
      section_constraint: "Constraint",
      constraint_type: "Constraint type",
      constraint_date: "Constraint date",
      asap: "As Soon As Possible",
      alap: "As Late As Possible",
      snet: "Start No Earlier Than",
      snlt: "Start No Later Than",
      fnet: "Finish No Earlier Than",
      fnlt: "Finish No Later Than",
      mso: "Must Start On",
      mfo: "Must Finish On",

      /* resource control */
      resources_filter_placeholder: "type to filter",
      resources_filter_label: "hide empty",
    },
  });
  proxy.$gantt.init(proxy.$refs.gantt);
  proxy.$gantt.parse(props.tasks);
  proxy.$gantt.createDataProcessor((entity, action, data, id) => {
    emit(`${entity}-updated`, id, action, data);
  });
  proxy.$gantt.attachEvent("onTaskSelected", (id) => {
    let task = proxy.$gantt.getTask(id);
    emit("task-selected", task);
  });

  proxy.$gantt.attachEvent("onTaskIdChange", (id, new_id) => {
    if (proxy.$gantt.getSelectedId() == new_id) {
      let task = proxy.$gantt.getTask(new_id);
      emit("task-selected", task);
    }
  });
});

const ganttAlert = (msg) => {
  proxy.$gantt.alert({
    title: "Alert",
    type: "alert-error",
    text: msg,
  });
};
defineExpose({
  ganttAlert,
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

app.vue

<template>
  <div class="container">
    <div class="right-container">
      <div class="gantt-selected-info">
        <div v-if="selectedTask">
          <h2>{{ selectedTask.text }}</h2>
          <span><b>ID: </b>{{ selectedTask.id }}</span
          ><br />
          <span><b>Progress: </b>{{ toPercent(selectedTask.progress) }}%</span
          ><br />
          <span><b>Start Date: </b>{{ niceDate(selectedTask.start_date) }}</span
          ><br />
          <span><b>End Date: </b>{{ niceDate(selectedTask.end_date) }}</span
          ><br />
        </div>
        <div v-else class="select-task-prompt">
          <h2>Click any task</h2>
        </div>
      </div>
      <ul class="gantt-messages">
        <li
          class="gantt-message"
          v-for="(message, index) in messages"
          :key="index"
        >
          {{ message }}
        </li>
      </ul>
    </div>
    <gantt
      ref="ganttDom"
      class="left-container"
      :tasks="tasks"
      @task-updated="logTaskUpdate"
      @link-updated="logLinkUpdate"
      @task-selected="selectTask"
    ></gantt>
  </div>
</template>

<script setup>
import gantt from "./components/gantt.vue";
import { ref, reactive, computed, onMounted,getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
let tasks = ref({
  data: [
    {
      id: 1,
      text: "Task #1",
      start_date: "2020-05-07",
      duration: 3,
      progress: 0.6,
    },
    {
      id: 2,
      text: "Task #2",
      start_date: "2020-11-20",
      duration: 3,
      progress: 0.4,
    },
  ],
  links: [{ id: 1, source: 1, target: 2, type: "0" }],
});
let messages = reactive([]);
let selectedTask = ref(null);
const toPercent = computed(() => {
  return function (val) {
    if (!val) return "0";
    return Math.round(+val * 100);
  };
});
const niceDate = computed(() => {
  return function (obj) {
    const date = new Date(obj);
    return `${date.getFullYear()} / ${date.getMonth() + 1} / ${date.getDate()}`;
  };
});

function addMessage(message) {
  messages.unshift(message);
  if (messages.length > 40) {
    messages.pop();
  }
}

function logTaskUpdate(id, mode, task) {
  let text = task && task.text ? ` (${task.text})` : "";
  let message = `Task ${mode}: ${id} ${text}`;
  addMessage(message);
}

function logLinkUpdate(id, mode, link) {
  let message = `Link ${mode}: ${id}`;
  if (link) {
    message += ` ( source: ${link.source}, target: ${link.target} )`;
  }
  addMessage(message);
}
function selectTask(task) {
  selectedTask.value = task;
}
onMounted(() => {
  console.log(proxy.$refs.ganttDom);
  // proxy.$refs.ganttDom.ganttAlert("Hello World");
});
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
.container {
  height: 100%;
  width: 100%;
}
.left-container {
  overflow: hidden;
  position: relative;
  height: 100%;
}
.right-container {
  border-right: 1px solid #cecece;
  float: right;
  height: 100%;
  width: 340px;
  box-shadow: 0 0 5px 2px #aaa;
  position: relative;
  z-index: 2;
}
.gantt-messages {
  list-style-type: none;
  height: 50%;
  margin: 0;
  overflow-x: hidden;
  overflow-y: auto;
  padding-left: 5px;
}
.gantt-messages > .gantt-message {
  background-color: #f4f4f4;
  box-shadow: inset 5px 0 #d69000;
  font-family: Geneva, Arial, Helvetica, sans-serif;
  font-size: 14px;
  margin: 5px 0;
  padding: 8px 0 8px 10px;
}
.gantt-selected-info {
  border-bottom: 1px solid #cecece;
  box-sizing: border-box;
  font-family: Geneva, Arial, Helvetica, sans-serif;
  height: 50%;
  line-height: 28px;
  padding: 10px;
}
.gantt-selected-info h2 {
  border-bottom: 1px solid #cecece;
}
.select-task-prompt h2 {
  color: #d9d9d9;
}
</style>
举报

相关推荐

0 条评论