vue3.0项目管理时间轴(计划任务)自定义组件
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
基于项目管理开发需求而封装,可以灵活的输入时间线,并在时间线上,进行不同的计划安排,简单直观,组件引用了antd3.0组件库的popover组件,逻辑清晰简单,可自行更改!
效果图:
代码块:
<template>
<div class="wapper" id="queryForm">
<div class="workLine">
<div v-for="(items,index) in task" :key="index"
:style="'width:'+items.Domwidth+'px; margin-left:'+items.width+'px'"
class="timetips">
<a-popover title="计划详情">
<template #content>
<p>{{items.content}}</p>
</template>
<a-button style="background-color: white;border: none;text-decoration:underline" type="link">
计划({{index+1}})
</a-button>
</a-popover>
<i class="ri-map-pin-3-fill"/>
</div>
</div>
<div class="lineFATH" style="display: flex;width: 100%;position: relative">
<div v-for="(item,index) in list" :key="item.id"
:style="'left:'+item.width+'px' "
class="timeCard">
<div class="timeCardMid">
<p class="timeCardMidLine"/>
</div>
<div :class="index===0?'ONE':''||index===(list.length-1)?'TWO':''" class="timeCardBot">
{{item.data}}
</div>
</div>
</div>
</div>
</template>
<script>
import {toRefs, ref, reactive, nextTick, onMounted, getCurrentInstance} from 'vue'
export default {
props: {
list: {
type: Array,
default: [
{
id: "1",
data: " 2022-01-12"
},
{
id: "2",
data: "2022-08-12"
},
{
id: "3",
data: "2022-03-12"
},
{
id: "4",
data: "2022-10-12"
},
{
id: "5",
data: "2022-12-12"
},
],
},
task: {
type: Array,
default: [
{
id: "1",
startTime: "2022-02-32",
endTime: "2022-05-12",
content: "这是我的第一个任务"
},
{
id: "2",
startTime: "2022-05-32",
endTime: "2022-08-12",
content: "这是我的第二个任务"
},
{
id: "3",
startTime: "2022-08-32",
endTime: "2022-11-12",
content: "这是我的第三个任务"
},
{
id: "4",
startTime: "2022-11-32",
endTime: "2022-12-12",
content: "这是我的第n个任务"
},
]
}
},
setup(props) {
const internalInstance = getCurrentInstance();
const Array = reactive({
/*时间轴*/
list: props.list,
/* 任务划分区域*/
task: props.task,
DomWidth: 0,
timeWidth: "",
evenly: '',
});
/*处理底部时间轴*/
const addDays = () => {
Array.list.forEach((item) => {
item.dueTime = Date.parse(item.data);
});
/*使用sort对Json数组的数据进行时间从小到大的排序*/
Array.list.sort(function (a, b) {
return a.dueTime - b.dueTime;
});
console.log(Array.list)
/*获取整个时间段的数据的总天数,并除以父级元素宽度,获取每一天元素可以分得的宽度*/
Array.timeWidth = compareDate(Array.list[0].data, Array.list[Array.list.length - 1].data);
Array.evenly = (Array.DomWidth / Array.timeWidth).toFixed(0);
/*将得到的底部时间段,进行计算,分配在主轴线上所占位置*/
for (let i = 0; i < Array.list.length; i++) {
Array.list[i].width = Array.evenly * compareDate(Array.list[0].data, Array.list[i].data)
}
/*起止位置分别定位为0以及100%*/
Array.list[0].width = 0;
Array.list[Array.list.length - 1].width = Array.DomWidth - 1
tasks()
};
/*处理任务时间轴*/
const tasks = () => {
for (let i = 0; i < Array.task.length; i++) {
Array.task[i].Domwidth = Array.evenly * compareDate(Array.task[i].startTime, Array.task[i].endTime);
if (i === 0) {
Array.task[i].width = 0
} else {
Array.task[i].width = Array.evenly * compareDate(Array.task[i - 1].endTime, Array.task[i].startTime)
}
}
internalInstance.ctx.$forceUpdate()
};
/*计算两个时间之间的天数*/
const compareDate = (start, end) => {
if (start === null || start.length === 0 || end === null || end.length === 0) {
return 0;
}
let arr = start.split("-");
let starttime = new Date(arr[0], parseInt(arr[1] - 1), arr[2]);
let starttimes = starttime.getTime();
let arrs = end.split("-");
let endtime = new Date(arrs[0], parseInt(arrs[1] - 1), arrs[2]);
let endtimes = endtime.getTime();
let intervalTime = endtimes - starttimes;//两个日期相差的毫秒数 一天86400000毫秒
let Inter_Days = ((intervalTime).toFixed(2) / 86400000) + 1;//加1,是让同一天的两个日期返回一天
return Inter_Days;
};
/*挂载时输出父元素的宽度*/
onMounted(() => {
/*或取父级元素的宽高*/
Array.DomWidth = document.getElementById('queryForm').clientWidth;
addDays()
});
return {
...toRefs(Array),
internalInstance,
compareDate
}
}
}
</script>
<style scoped>
.wapper {
margin: 20px 20px;
background-color: #39c1e0;
border: 1px solid #39c1e0;
}
p {
margin: 0;
padding: 0;
}
.timeCard {
position: absolute;
top: 0px;
height: 35px;
text-align: center;
}
.timeCardMid {
height: 35px;
}
.timeCardMidLine {
height: 35px;
width: 1px;
background-color: #39c1e0;
}
.timeCardBot {
height: 35px;
border-radius: 5px;
text-align: center;
line-height: 35px;
padding: 0 5px;
position: relative;
border: 1px solid #d9d9d9;
top: -0;
left: -50%;
width: 100px;
}
.workLine {
display: flex;
}
.ri-map-pin-3-fill {
position: absolute;
left: 50%;
top: -66%;
font-size: 16px;
color: #3d3d3d;
}
.ONE {
left: -20px !important;
}
.TWO {
left: -80%;
}
.timetips {
background-color: white;
position: relative;
border-radius: 5px;
height: inherit;
font-size: 12px;
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;
}
</style>
希望能够帮助到大家!
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献2条内容
所有评论(0)