当前位置: 首页 > wzjs >正文

全屏网站怎么做求职seo推荐

全屏网站怎么做,求职seo推荐,有关学校网站建设的建议,自建冷库费用在项目管理场景中,甘特图可能我们都不陌生,它是可视化任务进度和时间管理的利器。本文将演示如何使用Vue3结合Element Plus组件库,实现一个轻量级交互式甘特图组件,包含时间轴渲染、任务条、依赖关系展示等核心功能。 目录 一、…

在项目管理场景中,甘特图可能我们都不陌生,它是可视化任务进度和时间管理的利器。本文将演示如何使用Vue3结合Element Plus组件库,实现一个轻量级交互式甘特图组件,包含时间轴渲染、任务条、依赖关系展示等核心功能。

目录

一、安装组件

二、引入组件

三、使用组件实现甘特图

1.搭建框架

2.左侧固定列任务

3.右侧任务进度条

四、获取数据

五、滚动条实现分页

六、处理头部列表样式

七、全部代码


一、安装组件

对于项目的框架具体怎么安装,这里不做说明,下面是安装element plus组件方式。

npm install element-plus

二、引入组件

在框架中的main.js文件中引入刚安装的组件

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)

三、使用组件实现甘特图

1.搭建框架

在项目中可能甘特图这个使用的地方会很多,所以在这里作为一个组件来进行开发,首先是搭建一个具体的框架样式,然后给他填充相应的数据

<template><div class="gantt"><el-table:data="tableData"bordermax-height="calc(100vh - 25.5vw)"height="400px":empty-text="emptyText":loading="loading"ref="tableRef"></el-table></div>
</template><script setup>
const tableData = ref([])
const emptyText = ref('暂无数据')
const tableRef = ref(null)
const loading = ref(false)
</script><style lang="less" scoped>
.gantt {
}
</style>

2.左侧固定列任务

甘特图如果大致分的话,其实分为两大部分,分别为左侧的固定列展示每个任务的具体数据信息,右侧为 每个任务的时间进度条。接下来我们先实现左侧的固定列部分,该代码是在以上代码的基础上进行展示

 <!-- 左侧固定列 - 总体实施计划 --><el-table-column align="center" fixed="left" label="总体实施计划"><template #header><span class="header-overall-plan">总体实施计划</span></template><el-table-columnlabel="工单编号"prop="workOrderNum"align="center"min-width="120"fixed="left":show-overflow-tooltip="true"/><el-table-columnlabel="停电场所"prop="site"align="center"min-width="120"fixed="left":show-overflow-tooltip="true"/><el-table-columnlabel="停电范围"prop="range"align="center"min-width="120"fixed="left":show-overflow-tooltip="true"/><el-table-column label="进度" align="center" min-width="120" fixed="left"><template #default="scope"><span>计划</span><br /><span>实际</span></template></el-table-column></el-table-column>

3.右侧任务进度条

由于每个人任务的甘特图分为计划时间和实际时间,即在一个任务中需要显示两个任务进度条,所以在这里我们需要做一些处理。

<!-- 右侧甘特图部分 --><el-table-column align="center" label="检修甘特图"><template #header><span>检修甘特图</span></template><!-- 月份列 --><el-table-columnv-for="month in 12":key="month":label="`${currentYear}年${month}月`"align="center"min-width="150"><!-- 天数列 --><el-table-columnv-for="day in getDaysInMonth(currentYear, month)":key="`${currentYear}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`":prop="`${currentYear}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`":label="day.toString()"align="center"width="50"><template #default="scope"><div><i class="plan" v-if="isPlanDay(scope.row, scope.column.property)"></i><i class="empty" v-else></i><i :class="getActualityClass(scope.row)" v-if="isActualDay(scope.row, scope.column.property)"></i><i class="empty" v-else></i></div></template></el-table-column></el-table-column></el-table-column>

从上述的头部列表中我们可以看到使用了很多的方法,用于获取年份、月份和天数等,先来实现获取年份和月份的

// 当前年份
const currentYear = new Date().getFullYear()

接下来是获取天数的

// 获取指定月份的天数
const getDaysInMonth = (year, month) => {return new Date(year, month, 0).getDate()
}

然后就是要判断当前日期是否在计划时间的范围内,在写这个方法之前我们需要先来做个甘特图的配置

// 甘特图配置
const ganttConfig = {planBeginColumn: 'planBegin',planEndColumn: 'planEnd',actualityBeginColumn: 'actualityBegin',actualityEndColumn: 'actualityEnd'
}
// 判断当前日期是否在计划范围内
const isPlanDay = (row, currentDateStr) => {if (!currentDateStr || !row) return falseconst currentDay = new Date(currentDateStr)const begin = new Date(row[ganttConfig.planBeginColumn])const end = new Date(row[ganttConfig.planEndColumn])return currentDay >= begin && currentDay <= end
}

实际的也一样,需要做判断当前日期是否在实际范围内这样一个处理

// 判断当前日期是否在实际范围内
const isActualDay = (row, currentDateStr) => {if (!currentDateStr || !row || !row[ganttConfig.actualityBeginColumn] || !row[ganttConfig.actualityEndColumn])return falseconst currentDay = new Date(currentDateStr)const begin = new Date(row[ganttConfig.actualityBeginColumn])const end = new Date(row[ganttConfig.actualityEndColumn])return currentDay >= begin && currentDay <= end
}

由于对于实际时间的进度条颜色有区分的需求,所以还需要写个样式的方法,该方法可根据自身项目需要进行使用

const getActualityClass = row => {// 处理可能的null/undefined值const actualBegin = row.actualityBegin || ''const actualEnd = row.actualityEnd || ''// 增加trim处理防止空格干扰const hasActualBegin = actualBegin.trim() !== ''const hasActualEnd = actualEnd.trim() !== ''if (!hasActualBegin && !hasActualEnd) {return 'actuality-green'} else if (hasActualBegin && !hasActualEnd) {return 'actuality-yellow'} else {return 'actuality-grey'}
}

具体的样式代码

.gantt {// margin-top: 1vw;.plan {display: flex;width: calc(100% + 24px);height: 16px;background-color: #6dcaa6;margin: 0 -12px;/* border-radius: 15px; */}.actuality-green {display: flex;width: calc(100% + 24px);height: 16px;margin: 0 -12px;background-color: #6dcaa6;}.actuality-yellow {display: flex;width: calc(100% + 24px);height: 16px;margin: 0 -12px;background-color: #f59a23;}.actuality-grey {display: flex;width: calc(100% + 24px);height: 16px;margin: 0 -12px;background-color: #aaaaaa;}.empty {display: flex;width: calc(100% + 24px);height: 16px;margin: 0 -12px;}.legend {display: flex;line-height: 40px;flex-direction: row;justify-content: right;align-items: center;padding: 0 20px;i {width: 32px;height: 16px;}}:deep .el-table thead {color: #595858;}}

四、获取数据

以上代码概述完之后,甘特图大致的样式就可以实现了,接下来就是如何获取后端的数据进行展示,由于本案例获取后端数据的方法是封装axios后的,在这里不做过多的阐述

import { getManiProgressTable} from '@/api/home/home-center.js'
const getMainProgressData = params => {loading.value = truereturn new Promise((resolve, reject) => {getManiProgressTable(params).then(res => {if (res.code === 200 && res.data) {// console.log(res.data.total, '实时检修进度')total.value = res.data.total // 更新总条数tableData.value = res.data.data.map((item, index) => {return {workOrderNum: item.JHBH,site: item.TYDW,range: item.TDFW,actualityBegin: item.SJGZKSSJ.substring(0, 10),actualityEnd: item.SJGZJSSJ.substring(0, 10),planBegin: item.PZGZKSSJ.substring(0, 10),planEnd: item.PZGZJSSJ.substring(0, 10)}})resolve(res.data)} else {}}).catch(err => {reject(err)}).finally(() => {loading.value = false// 在数据加载完成后,恢复滚动位置setTimeout(() => {tableRef.value.$refs.bodyWrapper.scrollTop = currentScrollTop}, 100)})})
}

异步加载数据,由于该甘特图的数据过多,需要有分页的情况,下面代码将进行阐述如何做分页,在初始化加载数据时需要传分页参数

//定义开始入参
const initParams = ref({currentPage: 1,pageSize: 20
})
onMounted(() => {getMainProgressData(initParams.value)
})

五、滚动条实现分页

因为直接在 甘特图下方做分页效果太丑,所以新的需求是通过滚动条来实现分页效果展示数据,先在头部添加滚动事件

<el-table:data="tableData"bordermax-height="calc(100vh - 25.5vw)"height="400px":empty-text="emptyText":loading="loading"ref="tableRef"@scroll="handleScroll">

书写滚动分页事件方法

const pageSize = ref(20)
let currentPage = 1
const total = ref(0)
// 用于记录滚动位置
let currentScrollTop = 0
// 处理滚动事件,加载更多数据
const handleScroll = e => {if (e.scrollTop == 0) {return}const scrollHeight = tableRef.value.$refs.bodyWrapper.scrollHeightconst clientHeight = tableRef.value.$refs.tableBody.clientHeightconst scrollTop = Math.round(e.scrollTop) + 1// 是否触底判断const isBottom = scrollHeight + scrollTop >= clientHeightif (isBottom) {if (currentPage * pageSize.value < total.value) {// 记录当前滚动位置currentScrollTop = e.scrollTopcurrentPage++initParams.value = {currentPage,pageSize: pageSize.value}getMainProgressData(initParams.value)console.log('触底')}}
}

六、处理头部列表样式

由于以上书写的头部样式只是单纯的表格样式,过于简单,所以这里再重新做一下处理,在头部添加一个方法

<el-table:data="tableData"bordermax-height="calc(100vh - 25.5vw)"height="400px":empty-text="emptyText":loading="loading":header-cell-style="headerStyle"ref="tableRef"@scroll="handleScroll">

书写样式方法代码

const headerStyle = ({ column }) => {// console.log(column.label, 'column')if (column.label === '总体实施计划') {return { 'background-color': '#02A7F0' }}if (column.label === '检修甘特图') {return { 'background-color': '#FFE0B2' }}if (column.label === '进度' ||column.label === '工单编号' ||column.label === '停电场所' ||column.label === '停电范围') {return { 'background-color': '#BBDEFB' }}// const monthMatch = column.label?.match(/年(\d+)月/)// if (monthMatch) {//   return { 'background-color': parseInt(monthMatch[1]) % 2 ? '#FFCDD2' : '#C8E6C9' }// }const isMonthColumn = column.label?.includes('年') && column.label?.includes('月')const isDayColumn = column.property?.includes('-') // 通过prop属性判断是否为天数列if (isMonthColumn || isDayColumn) {// 从label或property中提取月份const month = isMonthColumn ? parseInt(column.label.match(/年(\d+)月/)[1]) : parseInt(column.property.split('-')[1])return {'background-color': month % 2 ? '#FFCDD2' : '#C8E6C9',padding: '8px 0' // 保持原有内边距样式}}return {}
}

七、全部代码

<template><div class="gantt"><el-table:data="tableData"bordermax-height="calc(100vh - 25.5vw)"height="400px":empty-text="emptyText":loading="loading":header-cell-style="headerStyle"ref="tableRef"@scroll="handleScroll"><!-- 左侧固定列 - 总体实施计划 --><el-table-column align="center" fixed="left" label="总体实施计划"><template #header><span class="header-overall-plan">总体实施计划</span></template><el-table-columnlabel="工单编号"prop="workOrderNum"align="center"min-width="120"fixed="left":show-overflow-tooltip="true"/><el-table-columnlabel="停电场所"prop="site"align="center"min-width="120"fixed="left":show-overflow-tooltip="true"/><el-table-columnlabel="停电范围"prop="range"align="center"min-width="120"fixed="left":show-overflow-tooltip="true"/><el-table-column label="进度" align="center" min-width="120" fixed="left"><template #default="scope"><span>计划</span><br /><span>实际</span></template></el-table-column></el-table-column><!-- 右侧甘特图部分 --><el-table-column align="center" label="检修甘特图"><template #header><span>检修甘特图</span></template><!-- 月份列 --><el-table-columnv-for="month in 12":key="month":label="`${currentYear}年${month}月`"align="center"min-width="150"><!-- 天数列 --><el-table-columnv-for="day in getDaysInMonth(currentYear, month)":key="`${currentYear}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`":prop="`${currentYear}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`":label="day.toString()"align="center"width="50"><template #default="scope"><div><i class="plan" v-if="isPlanDay(scope.row, scope.column.property)"></i><i class="empty" v-else></i><i :class="getActualityClass(scope.row)" v-if="isActualDay(scope.row, scope.column.property)"></i><i class="empty" v-else></i></div></template></el-table-column></el-table-column></el-table-column></el-table></div>
</template><script setup>
import {getManiProgressTable} from '@/api/home/home-center.js'
// 当前年份
const currentYear = new Date().getFullYear()
const emptyText = ref('暂无数据')
//定义开始入参
const initParams = ref({currentPage: 1,pageSize: 20
})
// 表格引用
const tableRef = ref(null)
const pageSize = ref(20)
let currentPage = 1
const total = ref(0)
const loading = ref(false)
const tableData = ref([
])
// 甘特图配置
const ganttConfig = {planBeginColumn: 'planBegin',planEndColumn: 'planEnd',actualityBeginColumn: 'actualityBegin',actualityEndColumn: 'actualityEnd'
}// 获取指定月份的天数
const getDaysInMonth = (year, month) => {return new Date(year, month, 0).getDate()
}// 判断当前日期是否在计划范围内
const isPlanDay = (row, currentDateStr) => {if (!currentDateStr || !row) return falseconst currentDay = new Date(currentDateStr)const begin = new Date(row[ganttConfig.planBeginColumn])const end = new Date(row[ganttConfig.planEndColumn])return currentDay >= begin && currentDay <= end
}// 判断当前日期是否在实际范围内
const isActualDay = (row, currentDateStr) => {if (!currentDateStr || !row || !row[ganttConfig.actualityBeginColumn] || !row[ganttConfig.actualityEndColumn])return falseconst currentDay = new Date(currentDateStr)const begin = new Date(row[ganttConfig.actualityBeginColumn])const end = new Date(row[ganttConfig.actualityEndColumn])return currentDay >= begin && currentDay <= end
}
const getActualityClass = row => {// 处理可能的null/undefined值const actualBegin = row.actualityBegin || ''const actualEnd = row.actualityEnd || ''// 增加trim处理防止空格干扰const hasActualBegin = actualBegin.trim() !== ''const hasActualEnd = actualEnd.trim() !== ''if (!hasActualBegin && !hasActualEnd) {return 'actuality-green'} else if (hasActualBegin && !hasActualEnd) {return 'actuality-yellow'} else {return 'actuality-grey'}
}
const headerStyle = ({ column }) => {// console.log(column.label, 'column')if (column.label === '总体实施计划') {return { 'background-color': '#02A7F0' }}if (column.label === '检修甘特图') {return { 'background-color': '#FFE0B2' }}if (column.label === '进度' ||column.label === '工单编号' ||column.label === '停电场所' ||column.label === '停电范围') {return { 'background-color': '#BBDEFB' }}// const monthMatch = column.label?.match(/年(\d+)月/)// if (monthMatch) {//   return { 'background-color': parseInt(monthMatch[1]) % 2 ? '#FFCDD2' : '#C8E6C9' }// }const isMonthColumn = column.label?.includes('年') && column.label?.includes('月')const isDayColumn = column.property?.includes('-') // 通过prop属性判断是否为天数列if (isMonthColumn || isDayColumn) {// 从label或property中提取月份const month = isMonthColumn ? parseInt(column.label.match(/年(\d+)月/)[1]) : parseInt(column.property.split('-')[1])return {'background-color': month % 2 ? '#FFCDD2' : '#C8E6C9',padding: '8px 0' // 保持原有内边距样式}}return {}
}
// 用于记录滚动位置
let currentScrollTop = 0
// 处理滚动事件,加载更多数据
const handleScroll = e => {if (e.scrollTop == 0) {return}const scrollHeight = tableRef.value.$refs.bodyWrapper.scrollHeightconst clientHeight = tableRef.value.$refs.tableBody.clientHeightconst scrollTop = Math.round(e.scrollTop) + 1// 是否触底判断const isBottom = scrollHeight + scrollTop >= clientHeightif (isBottom) {if (currentPage * pageSize.value < total.value) {// 记录当前滚动位置currentScrollTop = e.scrollTopcurrentPage++initParams.value = {...initParams.value,currentPage,pageSize: pageSize.value}getMainProgressData(initParams.value)console.log('触底')}}
}
const getMainProgressData = params => {loading.value = truereturn new Promise((resolve, reject) => {getManiProgressTable(params).then(res => {if (res.code === 200 && res.data) {// console.log(res.data.total, '实时检修进度')total.value = res.data.total // 更新总条数tableData.value = res.data.data.map((item, index) => {return {workOrderNum: item.JHBH,site: item.TYDW,range: item.TDFW,actualityBegin: item.SJGZKSSJ.substring(0, 10),actualityEnd: item.SJGZJSSJ.substring(0, 10),planBegin: item.PZGZKSSJ.substring(0, 10),planEnd: item.PZGZJSSJ.substring(0, 10)}})resolve(res.data)} else {}}).catch(err => {reject(err)}).finally(() => {loading.value = false// 在数据加载完成后,恢复滚动位置setTimeout(() => {tableRef.value.$refs.bodyWrapper.scrollTop = currentScrollTop}, 100)})})
}
onMounted(() => {getFilterData()// init()getMainProgressData(initParams.value)
})
</script><style lang="less" scoped>.gantt {// margin-top: 1vw;.plan {display: flex;width: calc(100% + 24px);height: 16px;background-color: #6dcaa6;margin: 0 -12px;/* border-radius: 15px; */}.actuality-green {display: flex;width: calc(100% + 24px);height: 16px;margin: 0 -12px;background-color: #6dcaa6;}.actuality-yellow {display: flex;width: calc(100% + 24px);height: 16px;margin: 0 -12px;background-color: #f59a23;}.actuality-grey {display: flex;width: calc(100% + 24px);height: 16px;margin: 0 -12px;background-color: #aaaaaa;}.empty {display: flex;width: calc(100% + 24px);height: 16px;margin: 0 -12px;}.legend {display: flex;line-height: 40px;flex-direction: row;justify-content: right;align-items: center;padding: 0 20px;i {width: 32px;height: 16px;}}:deep .el-table thead {color: #595858;}}
</style>

http://www.dtcms.com/wzjs/71872.html

相关文章:

  • 自己的网站做一些诱惑百度指数有哪些功能
  • 做网站代理拉不到人武汉百度关键词推广
  • 网站风格定位怎么写做百度推广
  • 合肥公司注册平台seo推广论坛
  • 淘宝客网站做百度推广甘肃搜索引擎网络优化
  • 榆林网站建设哪家好seosem顾问
  • 网站建设与管理习题一自动推广引流app
  • 小型网站开发各城市首轮感染高峰期预测
  • 360借条平台是合法的吗重庆百度快速优化
  • 如何设计网站logo自媒体平台注册
  • 网站做优化有什么用吗武汉做网页推广公司
  • 今天出入深圳最新规定企业网站seo优化
  • 成都营销型网站建设中账号seo网站诊断分析报告
  • 品牌网站建设黑白I狼J百度一下首页登录入口
  • 网站开发的实验报告体育新闻最新消息
  • 医院网站管理系统网络公司网络推广
  • 做跨境都有哪些网站网站制作定制
  • 和县网站建设网络营销的类型
  • 危险网站解除百度权重查询网址
  • 响水网站建设公司网络营销与直播电商是干什么的
  • 物流网站建设方案搜狐视频
  • 广东电子商务网站建设价格搜索引擎优化的基本手段
  • 我需要把网站做值得收藏的五个搜索引擎
  • 微信卖水果链接网站怎么做如何利用互联网进行宣传推广
  • 钓鱼网站下载appseo创业
  • 深圳做网站推广优化中国职业培训在线平台
  • 品牌策划公司收费seo优化排名公司
  • 企业在哪里查询长沙seo服务
  • 专业做网站设计公司价格怎么制作一个网页
  • 简述网站主要流程实时热搜