前言
网上有很多的vue的流程组件,但是本人不喜欢很多冗余的代码,喜欢动手敲代码; 刚开始写的时候,确实没法下笔,最后一层一层剥离,总算实现了; 大家可以参考我写的代码,可以拿过去定制化修改(因为每个项目的UI风格不一样,更多是样式的不一样); 关于功能,多一些点击事件呀什么的,我相信对大家来说是问题不大的,难度的部分是怎么画出来; 下面的代码支持vue2
也支持vue3
,只不过是选项式,反正都支持。不喜欢的,可以稍微改下script
部分,改成组合式API
就好了; 对于其他框架react
等,只要是前端,百变不离其踪,重要的是思想,稍微改改就好了,JavaScript部分很少,改起来也方便。
代码
< template>
< div class = " process-tree" >
< div
v-for = " (item, index) in data"
:key = " index"
class = " process-tree__row"
>
< div
class = " process-tree__row__box"
:class = " {
// 左横线
'line-left': index !== 0,
// 右横线
'line-right': index !== data.length - 1,
}"
>
< div
class = " process-tree__row__box--container"
:class = " {
// 向上竖线
'line-bottom': item.children && item.children.length > 0,
// 向下竖线
'line-top': !isTreeRoot,
}"
>
< div
v-if = " !isTreeRoot"
class = " process-tree__row__box--container__triangle"
/>
< div class = " process-tree__row__box--container__content" >
{{ item.title }}
</ div>
</ div>
</ div>
< process-tree
:data = " item.children"
:isTreeRoot = " false"
/>
</ div>
</ div>
</ template>
< script>
export default {
name : "process-tree" ,
props : {
data : {
type : Array,
default : ( ) => [ ] ,
} ,
isTreeRoot : {
type : Boolean,
default : true ,
} ,
} ,
} ;
</ script>
< style lang = " scss" scoped >
// 底部的线高度,也可以当作容器之间的间距
$line-bottom-length : 20px;
// 线粗细
$line-crude : 1px;
// 线颜色
$line-color : rgba ( 43, 163, 253) ;
// 盒子里面的容器的border粗细
$container-border-width : 1px;
.process-tree {
display : flex;
&__row {
&__box {
display : flex;
justify-content : center;
position : relative;
&--container {
position : relative;
display : flex;
justify-content : center;
background-color : #eafffc;
border : $container-border-width solid $line-color;
padding : 4px;
margin : $line-bottom-length;
color : #fff;
&__triangle {
position : absolute;
border-left : 4.5px solid transparent;
border-right : 4.5px solid transparent;
border-top : 6px solid rgba ( 43, 163, 253, 0.7) ;
top : -6px;
}
&__content {
display : flex;
flex-direction : column;
justify-content : space-between;
align-items : center;
color : black;
padding : 8px 40px;
}
}
}
}
// 线样式
@mixin line {
content : "" ;
display : block;
height : $line-bottom-length;
position : absolute;
left : 0;
right : 0;
margin : auto;
background-color : $line-color;
}
// 向下的线
.line-bottom {
&::after {
@include line;
width : $line-crude;
bottom : -$line-bottom-length - $container-border-width;
}
}
// 向上的线
.line-top {
&::before {
@include line;
width : $line-crude;
top : -$line-bottom-length - $container-border-width;
}
}
// 向左的线
.line-left {
&::after {
@include line;
width : calc ( 50%) ;
height : $line-crude;
left : calc ( -50%) ;
top : 0;
}
}
// 向右的线
.line-right {
&::before {
@include line;
width : calc ( 50%) ;
height : $line-crude;
right : calc ( -50%) ;
top : 0;
}
}
}
</ style>
< ProcessTree :data= "problemTreeData" />
problemTreeData: [
{
title: "1" ,
children: [
{
title: "2" ,
children: [
{
title: "3" ,
children: [
{
title: "4" ,
} ,
] ,
} ,
{
title: "3" ,
children: [
{
title: "4" ,
} ,
] ,
} ,
] ,
} ,
{
title: "2" ,
} ,
] ,
} ,
]
效果图