最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue甘特圖vxe-gantt實現(xiàn)點擊任務(wù)條彈出編輯表單效果

 更新時間:2026年03月27日 09:45:40   作者:zhiy3  
本文將介紹如何使用 vxe-gantt 組件實現(xiàn)點擊任務(wù)條彈出編輯表單的功能,支持對任務(wù)的名稱、時間、進度、負責(zé)人、圖片附件等信息進行編輯,感興趣的朋友跟隨小編一起看看吧

基于 vxe-gantt 實現(xiàn)任務(wù)條點擊編輯表單

在項目管理中,甘特圖是展示任務(wù)進度的核心組件。本文將介紹如何使用 vxe-gantt 組件實現(xiàn)點擊任務(wù)條彈出編輯表單的功能,支持對任務(wù)的名稱、時間、進度、負責(zé)人、圖片附件等信息進行編輯。

效果

點擊甘特圖中的任意任務(wù)條,系統(tǒng)會彈出模態(tài)框,展示當前任務(wù)的詳細表單,編輯保存后甘特圖視圖自動刷新。

代碼

<template>
  <div>
    <vxe-gantt ref="ganttRef" v-bind="ganttOptions" v-on="ganttEvents" />
    <vxe-modal
      v-model="editModalVisible"
      title="編輯任務(wù)"
      width="680"
      height="620"
      resize
      destroy-on-close
      show-footer
      show-confirm-button
      show-cancel-button
      :confirm-closable="false"
      @confirm="handleConfirm"
    >
      <vxe-form ref="formRef" v-bind="formOptions" />
    </vxe-modal>
  </div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { VxeUI } from 'vxe-pc-ui'
import XEUtils from 'xe-utils'
import axios from 'axios'
// ---------- 狀態(tài)管理 ----------
const editModalVisible = ref(false)
const currentTask = ref(null)        // 當前正在編輯的任務(wù)
const ganttRef = ref()
const formRef = ref()
// ---------- 甘特圖配置 ----------
const ganttOptions = reactive({
  border: true,
  taskConfig: {
    titleField: 'name',        // 任務(wù)名稱字段
    startField: 'startDate',   // 開始時間字段
    endField: 'endDate',       // 結(jié)束時間字段
    progressField: 'progress'  // 進度字段
  },
  taskBarConfig: {
    showProgress: true,        // 顯示進度百分比
    showContent: true,         // 顯示任務(wù)名稱
    barStyle: {
      bgColor: '#f56565',      // 未完成部分顏色
      completedBgColor: '#65c16f' // 已完成部分顏色
    }
  },
  taskViewConfig: {
    tableStyle: { width: 380 } // 左側(cè)任務(wù)列表寬度
  },
  columns: [
    { field: 'name', title: '任務(wù)名稱', minWidth: 160 },
    { field: 'startDate', title: '開始時間', width: 100 },
    { field: 'endDate', title: '結(jié)束時間', width: 100 },
    { field: 'progress', title: '進度', width: 60 },
    { field: 'responsibleBy', title: '負責(zé)人', width: 140 },
    { field: 'description', title: '備注', width: 200 },
    { field: 'createBy', title: '創(chuàng)建人', width: 160 },
    { field: 'imgList', title: '圖片', width: 160, cellRender: imageCellRender },
    { field: 'updateBy', title: '最后更新人', width: 180 },
    { field: 'createDate', title: '創(chuàng)建時間', width: 140 },
    { field: 'updateDate', title: '更新時間', width: 140 }
  ],
  data: []
})
// ---------- 表格渲染器配置 ----------
const imageCellRender = reactive({
  name: 'VxeImage',
  props: { width: 36, height: 36 }
})
// ---------- 表單上傳配置 ----------
const imageUploadRender = reactive({
  name: 'VxeUpload',
  props: {
    mode: 'image',
    multiple: true,
    urlMode: true,
    moreConfig: { maxCount: 2 },
    uploadMethod: async ({ file }) => {
      const formData = new FormData()
      formData.append('file', file)
      const res = await axios.post('/publicapi/api/pub/upload/single', formData)
      return res.data  // 期望返回 { url: '...' }
    }
  }
})
const fileUploadRender = reactive({
  name: 'VxeUpload',
  props: {
    multiple: true,
    moreConfig: { maxCount: 2 },
    uploadMethod: async ({ file }) => {
      const formData = new FormData()
      formData.append('file', file)
      const res = await axios.post('/publicapi/api/pub/upload/single', formData)
      return res.data  // 期望返回 { url: '...' }
    }
  }
})
// ---------- 表單配置 ----------
const formOptions = reactive({
  titleWidth: 'auto',
  titleAlign: 'right',
  titleColon: true,
  data: {
    name: '',
    startDate: '',
    endDate: '',
    progress: 0,
    responsibleBy: '',
    description: '',
    imgList: [],
    fileList: []
  },
  rules: {
    name: [{ required: true, message: '任務(wù)名稱不能為空' }],
    startDate: [{ required: true, message: '開始時間不能為空' }],
    endDate: [{ required: true, message: '結(jié)束時間不能為空' }],
    progress: [{ required: true, message: '進度不能為空' }],
    responsibleBy: [{ required: true, message: '負責(zé)人不能為空' }]
  },
  items: [
    { field: 'name', title: '任務(wù)名稱', span: 24, itemRender: { name: 'VxeInput' } },
    { field: 'startDate', title: '開始時間', span: 12, itemRender: { name: 'VxeDatePicker' } },
    { field: 'endDate', title: '結(jié)束時間', span: 12, itemRender: { name: 'VxeDatePicker' } },
    { field: 'progress', title: '進度', span: 12, itemRender: { name: 'VxeNumberInput', props: { type: 'integer', min: 0, max: 100 } } },
    { field: 'responsibleBy', title: '負責(zé)人', span: 12, itemRender: { name: 'VxeInput' } },
    { field: 'description', title: '備注', span: 24, itemRender: { name: 'VxeInput' } },
    { field: 'imgList', title: '圖片', span: 24, itemRender: imageUploadRender },
    { field: 'fileList', title: '附件', span: 24, itemRender: fileUploadRender }
  ]
})
// ---------- 事件處理 ----------
const ganttEvents = {
  taskBarClick: ({ row }) => {
    // 將行數(shù)據(jù)解構(gòu)到表單數(shù)據(jù)中
    XEUtils.destructuring(formOptions.data, row)
    currentTask.value = row
    editModalVisible.value = true
  }
}
const handleConfirm = async () => {
  const formInstance = formRef.value
  if (!formInstance) return
  const errors = await formInstance.validate()
  if (errors) return  // 校驗失敗,阻止提交
  const task = currentTask.value
  if (task) {
    // 更新任務(wù)數(shù)據(jù)
    Object.assign(task, {
      name: formOptions.data.name,
      startDate: formOptions.data.startDate,
      endDate: formOptions.data.endDate,
      progress: formOptions.data.progress
    })
  }
  editModalVisible.value = false
  VxeUI.modal.message({ content: '保存成功', status: 'success' })
  // 刷新甘特圖視圖
  if (ganttRef.value) {
    ganttRef.value.refreshTaskView()
  }
}
</script>

核心實現(xiàn)解析

1. 任務(wù)點擊事件綁定

通過 ganttEvents 對象定義 taskBarClick 回調(diào),當用戶點擊任務(wù)條時觸發(fā):

const ganttEvents = {
  taskBarClick: ({ row }) => {
    // 將點擊的任務(wù)數(shù)據(jù)填充到表單
    XEUtils.destructuring(formOptions.data, row)
    currentTask.value = row
    editModalVisible.value = true
  }
}
  • row 參數(shù)包含當前任務(wù)的所有字段
  • 使用 XEUtils.destructuring 將行數(shù)據(jù)映射到表單的 data 對象,實現(xiàn)數(shù)據(jù)填充

2. 表單數(shù)據(jù)綁定

表單通過 vxe-formdata 屬性與 formOptions.data 綁定,當用戶修改表單內(nèi)容時,數(shù)據(jù)實時同步:

const formOptions = reactive({
  data: {
    name: '',
    startDate: '',
    endDate: '',
    progress: 0,
    // ... 其他字段
  },
  // ...
})

3. 保存與刷新

點擊模態(tài)框的“確認”按鈕時,執(zhí)行 handleConfirm

const handleConfirm = async () => {
  // 1. 表單校驗
  const errors = await formRef.value.validate()
  if (errors) return
  // 2. 更新任務(wù)數(shù)據(jù)
  Object.assign(currentTask.value, {
    name: formOptions.data.name,
    startDate: formOptions.data.startDate,
    endDate: formOptions.data.endDate,
    progress: formOptions.data.progress
  })
  // 3. 關(guān)閉模態(tài)框并提示
  editModalVisible.value = false
  VxeUI.modal.message({ content: '保存成功', status: 'success' })
  // 4. 刷新甘特圖視圖
  ganttRef.value?.refreshTaskView()
}
  • 表單校驗:確保必填項已填寫
  • 數(shù)據(jù)更新:使用 Object.assign 將表單數(shù)據(jù)寫回原任務(wù)對象
  • 視圖刷新:調(diào)用 refreshTaskView() 讓甘特圖重新渲染

4. 文件上傳支持

通過 VxeUpload 組件實現(xiàn)圖片和附件的上傳功能:

const imageUploadRender = reactive({
  name: 'VxeUpload',
  props: {
    mode: 'image',
    multiple: true,
    urlMode: true,
    moreConfig: { maxCount: 2 },
    uploadMethod: async ({ file }) => {
      const formData = new FormData()
      formData.append('file', file)
      const res = await axios.post('/api/upload', formData)
      return res.data  // 返回 { url: '...' }
    }
  }
})
  • urlMode 啟用后,組件直接管理 URL 列表,無需手動處理文件對象
  • uploadMethod 定義上傳邏輯,返回上傳后的文件 URL

[https://gantt.vxeui.com]

到此這篇關(guān)于vue甘特圖vxe-gantt實現(xiàn)點擊任務(wù)條彈出編輯表單效果的文章就介紹到這了,更多相關(guān)vue甘特圖vxe-gantt內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue使用Google地圖的實現(xiàn)示例代碼

    vue使用Google地圖的實現(xiàn)示例代碼

    這篇文章主要介紹了vue使用Google地圖的實現(xiàn)示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • vue3如何定義變量及ref、reactive、toRefs特性說明

    vue3如何定義變量及ref、reactive、toRefs特性說明

    這篇文章主要介紹了vue3如何定義變量及ref、reactive、toRefs特性說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • vue-virtual-scroller 的使用詳解

    vue-virtual-scroller 的使用詳解

    vue-virtual-scroller是一個高度可定制的虛擬滾動列表插件,它可以在大量數(shù)據(jù)下提供高性能的渲染和滾動,這篇文章主要介紹了vue-virtual-scroller 的使用,需要的朋友可以參考下
    2023-07-07
  • 前端處理axios請求下載后端返回的文件流代碼實例

    前端處理axios請求下載后端返回的文件流代碼實例

    使用axios可以很方便地獲取后端返回的文件流數(shù)據(jù),并在前端直接在瀏覽器下載,這篇文章主要給大家介紹了關(guān)于前端處理axios請求下載后端返回的文件流的相關(guān)資料,需要的朋友可以參考下
    2024-07-07
  • 詳解Vue微信授權(quán)登錄前后端分離較為優(yōu)雅的解決方案

    詳解Vue微信授權(quán)登錄前后端分離較為優(yōu)雅的解決方案

    這篇文章主要介紹了詳解Vue微信授權(quán)登錄前后端分離較為優(yōu)雅的解決方案,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • vue項目完成后如何實現(xiàn)項目優(yōu)化的示例

    vue項目完成后如何實現(xiàn)項目優(yōu)化的示例

    本文主要介紹了vue項目完成后如何實現(xiàn)項目優(yōu)化的示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • ElementUI中el-tree節(jié)點的操作的實現(xiàn)

    ElementUI中el-tree節(jié)點的操作的實現(xiàn)

    這篇文章主要介紹了ElementUI中el-tree節(jié)點的操作的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 解決vue項目中出現(xiàn)Invalid Host header的問題

    解決vue項目中出現(xiàn)Invalid Host header的問題

    這篇文章主要介紹了解決vue項目中出現(xiàn)"Invalid Host header"的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • 在Vue3中實現(xiàn)懶加載功能的代碼示例

    在Vue3中實現(xiàn)懶加載功能的代碼示例

    在現(xiàn)代前端開發(fā)中,懶加載是一種提高應(yīng)用性能和用戶體驗的重要技術(shù),尤其是在處理較大圖片或長列表數(shù)據(jù)時,本文將使用 Vue 3 和其新推出的 setup 語法糖來實現(xiàn)懶加載功能,并提供具體的示例代碼,需要的朋友可以參考下
    2024-09-09
  • Vue.js路由實現(xiàn)選項卡簡單實例

    Vue.js路由實現(xiàn)選項卡簡單實例

    這篇文章主要為大家詳細介紹了Vue.js路由實現(xiàn)選項卡簡單實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07

最新評論

郁南县| 拉萨市| 静宁县| 南溪县| 和田县| 博客| 邓州市| 宽甸| 乐陵市| 德昌县| 忻城县| 共和县| 井陉县| 唐山市| 华池县| 屏边| 凤冈县| 唐河县| 集贤县| 香港| 沭阳县| 沁阳市| 赤壁市| 衡南县| 株洲县| 象州县| 吉林省| 华宁县| 青阳县| 满城县| 洛隆县| 龙海市| 曲周县| 白沙| 江孜县| 济宁市| 方正县| 宾川县| 鞍山市| 银川市| 易门县|