box矩形外四向箭头(基于vue)

1、入口文件(FlowChart.vue)

<template>
  <div class="flow-chart-wrap">
    <div class="row-wrap"><!--第一行-->
      <div class="col-wrap">
        <!--        <Box :styleObject="styleObject" :box-name="boxName" :top-line="true" :top-down="true" :left-line="true"
                     :left-right="true"
                     :right-line="true" :bottom-line="true"
                     :bottom-up="true"></Box>-->
      </div>
      <div class="col-wrap"></div>
      <div class="col-wrap">
        <Box :styleObject="styleRectangle" :box-name="boxName" :bottom-line="true" :bottom-up="true"
        ></Box>
      </div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
    </div>
    <div class="row-wrap"><!--第2行-->
      <div class="col-wrap">
        <Box :styleObject="styleRadius" :box-name="boxName"
             :right-line="true"></Box>
      </div>
      <div class="col-wrap">
        <Box :styleObject="styleRectangle" :box-name="boxName" :top-down="true" :left-line="true"
             :left-right="true"
             :right-line="true" :bottom-line="true"
        ></Box>
      </div>
      <div class="col-wrap">
        <Box :styleObject="styleRectangle" :box-name="boxName" :top-line="true" :left-line="true"
             :left-right="true"
             :right-line="true" :bottom-line="true"
        ></Box>
      </div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
    </div>
    <div class="row-wrap"><!--第3行-->
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
    </div>
    <div class="row-wrap"><!--第4行-->
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
    </div>
    <div class="row-wrap"><!--第5行-->
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
    </div>
    <div class="row-wrap"><!--第6行-->
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
    </div>
    <div class="row-wrap"><!--第7行-->
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
      <div class="col-wrap"></div>
    </div>
  </div>
</template>

<script>
  import Box from "./Box"

  export default {
    name: "Flowchart",
    components: {
      Box
    },
    data() {
      return {
        styleRectangle: {
          height: '50px',
          border: '1px solid #000000'
        },
        styleRadius: {
          'border': '1px solid #000000',
          'border-radius': '20px',
          'height': '40px'
        },
        boxName: "未按时竣工"
      }
    }
  }
</script>

<style lang="scss" scoped>
  .flow-chart-wrap {
    $boxHeight: 100%;
    $boxWidth: 100%;
     100%;
    height: 100%;
    position: relative;
    display: flex;
    flex-direction: column;

    .row-wrap {
      flex: 1;
      display: flex;
      background: #dcdfe6;

      .col-wrap {
        flex: 1;
        border: 1px solid #ffffff;
        display: flex;
        justify-items: center;
        align-items: center;
      }
    }
  }
</style>

2、组件文件(Box.vue)

<template>
  <div class="box-wrap">
    <div class="top-wrap" :class="{ 'top-line': topLine }">
      <div :class="{ 'top-down-arrow': topLine && topDown }">
      </div>
    </div>
    <div class="middle-wrap">
      <div class="left-side" :class="{ 'left-line': leftLine }">
        <div :class="{ 'left-right-arrow': leftLine && leftRight }">
        </div>
      </div>
      <div class="middle-side" >
        <div class="name-wrap" v-bind:style="styleObject">
          {{boxName}}
        </div>
      </div>
      <div class="right-side" :class="{ 'right-line': rightLine }">
      </div>
    </div>
    <div class="bottom-wrap" :class="{ 'bottom-line': bottomLine }">
      <div :class="{ 'bottom-up-arrow': bottomLine && bottomUp }">
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    name: "Box",
    props: {
      styleObject: {
        type: Object,
        default: () => {
          return {
            'color': '#000000',
            'border': '1px solid #000000'
          }
        }
      },
      boxName: {
        type: String,
        default: ""
      },
      topDown: {
        type: Boolean,
        default: () => {
          return false
        }
      },
      leftRight: {
        type: Boolean,
        default: () => {
          return false
        }
      },
      bottomUp: {
        type: Boolean,
        default: () => {
          return false
        }
      },
      topLine: {
        type: Boolean,
        default: () => {
          return false
        }
      },
      leftLine: {
        type: Boolean,
        default: () => {
          return false
        }
      },
      rightLine: {
        type: Boolean,
        default: () => {
          return false
        }
      },
      bottomLine: {
        type: Boolean,
        default: () => {
          return false
        }
      },
    },
    data() {
      return {}
    }
  }
</script>

<style lang="scss" scoped>
  .box-wrap {
    position: relative;
    display: flex;
     100%;
    height: 100%;
    flex-direction: column;

    /**/
    .top-line { //无箭头直线
      &:before {
        content: "";
        position: absolute;
        top: 0;
        left: calc(50% - 0.5px);
        height: 100%;
         1px;
        background: #000000;
      }
    }

    .top-down-arrow { //上部分向下的箭头直线
      position: absolute;
      bottom: -6px;
      left: calc(50% - 5.5px);
       0;
      height: 0;
      border: 6px solid #000000;
      border-color: #000000 transparent transparent;
    }

    /**/
    .right-line { //无箭头直线
      &:before {
        content: "";
        position: absolute;
        top: calc(50% - 0.5px);
        left: 0;
        height: 1px;
         100%;
        background: #000000;
      }
    }

    /**/
    .bottom-line { //无箭头直线
      &:before {
        content: "";
        position: absolute;
        top: 0;
        left: calc(50% - 0.5px);
        height: 100%;
         1px;
        background: #000000;
      }
    }
    .bottom-up-arrow{ //下部分向上的箭头直线
      position: absolute;
      top: -6px;
      left: calc(50% - 5.5px);
       0;
      height: 0;
      border: 6px solid #000000;
      border-color: transparent transparent #000000;
    }

    /**/
    .left-line { //无箭头直线
      &:before {
        content: "";
        position: absolute;
        top: calc(50% - 0.5px);
        left: 0;
        height: 1px;
         100%;
        background: #000000;
      }
    }
    .left-right-arrow{ //左部分向右的箭头直线
      position: absolute;
      top: calc(50% - 5.5px);
      right: -6px;
       0;
      height: 0;
      border: 6px solid #000000;
      border-color: transparent transparent transparent #000000;
    }

    .top-wrap {
      position: relative;
      flex: 1;
      background: rgba(11, 189, 253, 0.15);
    }

    .middle-wrap {
      position: relative;
      /*flex: 3;*/
      background: rgba(11, 189, 253, 0.4);
      display: flex;

      .left-side {
        position: relative;
        flex: 1;
        background: rgba(0, 184, 63, 0.2);
      }

      .middle-side {
        position: relative;
        flex: 4;
        background: rgba(0, 184, 63, 0.44);
        display: flex;
        justify-content: center;
        align-items: center;
        justify-items: center;
        text-align: center;
        .name-wrap{
           100%!important;
          display: flex;
          justify-content: center;
          align-items: center;
          justify-items: center;
          text-align: center;
        }
      }

      .right-side {
        position: relative;
        flex: 1;
        background: #00B83F;
      }
    }

    .bottom-wrap {
      position: relative;
      flex: 1;
      background: #0bbdfd;
    }
  }
</style>
原文地址:https://www.cnblogs.com/yiliangmi/p/15676534.html