纯vue手写流程组件

前言

  • 网上有很多的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",
      },
    ],
  },
]
  • 效果图
相关推荐
大霸王龙36 分钟前
基于HTML的邮件发送状态查询界面设计示例
前端·javascript·html
z26373056113 小时前
为什么后端路由需要携带 /api 作为前缀?前端如何设置基础路径 /api?
前端
eggcode5 小时前
CSS选择器
前端·css
老胡说前端5 小时前
css white-space: pre-line; 用处大
前端·css
还是鼠鼠6 小时前
Node.js 包与 npm 详解:使用 npm 的重要注意事项与最佳实践
前端·javascript·vscode·node.js
图扑软件6 小时前
图扑软件 2D 组态:工业组态与硬件监控的物联网赋能
javascript·人工智能·物联网·低代码·数字孪生·可视化·工业组态
仿生狮子7 小时前
Reka UI 是个啥?
vue.js·nuxt.js·ui kit
不能只会打代码7 小时前
六十天前端强化训练之第二十六天之Vue Router 动态路由参数大师级详解
前端·javascript·vue.js·vue router·动态路由参数
不吃香菜的猪7 小时前
vue+echarts实现饼图组件(实现左右联动并且数据量大时可滚动)
前端·javascript·echarts
旺代7 小时前
CSS平面转换
前端·css