前言
- 网上有很多的vue的流程组件,但是本人不喜欢很多冗余的代码,喜欢动手敲代码;
- 刚开始写的时候,确实没法下笔,最后一层一层剥离,总算实现了;
- 大家可以参考我写的代码,可以拿过去定制化修改(因为每个项目的UI风格不一样,更多是样式的不一样);
- 关于功能,多一些点击事件呀什么的,我相信对大家来说是问题不大的,难度的部分是怎么画出来;
- 下面的代码支持
vue2
也支持vue3
,只不过是选项式,反正都支持。不喜欢的,可以稍微改下script
部分,改成组合式API
就好了;
- 对于其他框架
react
等,只要是前端,百变不离其踪,重要的是思想,稍微改改就好了,JavaScript部分很少,改起来也方便。
代码
html
复制代码
<!--
* @author kjprime
* @description 流程组件
-->
<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: {
/**
* @type {Array}
* @default []
* @example
* [
* {
* title: "1",
* children: []
* }
* ]
* @description 数据
*/
data: {
type: Array,
default: () => [],
},
// 是否为数的root节点
// 其实可以通过传父亲与子,通过对比是不是root就可以判断,但是感觉没有必要,直接通过prop可以解决。
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>
bash
复制代码
<ProcessTree :data="problemTreeData" />
problemTreeData: [
{
title: "1",
children: [
{
title: "2",
children: [
{
title: "3",
children: [
{
title: "4",
},
],
},
{
title: "3",
children: [
{
title: "4",
},
],
},
],
},
{
title: "2",
},
],
},
]
- 效果图
