橫向和縱向流程圖新增

<template>
  <div class="view-container car-detail-view">
        <div class="detail-center">
          <div id="stageCanvas" class="stage-content">
                      <div class="item" v-for="(item,index) in stageData" :key="item.id"  :style="getPosition(index,'x')" @mouseover="mouseoverHandle" @mouseout="mouseoutHandle">
                              <span class="text-x">{{item.name}}</span>
                              <span><el-icon @click="deleteStage(item,'x')" ><CircleClose /></el-icon></span>
                              <div class="children" v-for="(child,index) in item.children" :key="child.id" :style="getPosition(index,'y')" @mouseover.stop>
                                    <span class="text-y">{{child.name}}</span>
                                    <span><el-icon @click="deleteStage(child,'y',item)"><CircleClose /></el-icon></span>
                              </div>
                               <div class="children add-btn"  @click="addStage(item.children,'y')" :style="getPosition(item.children.length,'y')" @mouseover.stop>
                                     <span class="icon iconfont icon-increase"></span>   <!-- y新增-->
                                      <span>并行任務 </span>
                               </div>
                        </div>
                        <div class="item add-btn"  @click="addStage(stageData,'x')" :style="getPosition(stageData.length,'x')" @mouseover="mouseoverHandle" @mouseout="mouseoutHandle"> <!-- x新增-->
                            <span class="icon iconfont icon-increase"></span>
                            <span>{{stageData.length > 0 ?"串行任務":'新增'}}</span>
                        </div>

                </div>
        </div>
        <el-dialog   :model-value="stageAddVisible" title="添加階段" @close="closeDialog"   width="518px" >
          <div>
            <el-form :rules="stageRules" ref="ruleFormRefStage"  label-width="120px"  :model="stageDialogData">
                     <el-form-item label="階段:" prop="data">
                      <el-select   :multiple="false" v-model="stageDialogData.data" :popper-append-to-body="false" placeholder="請選擇">
                            <el-option  v-for="item in stageOptionData"   :key="item.id"  :label="item.name"  :value="item.name" ></el-option>
                      </el-select>
                    </el-form-item>
            </el-form>
          </div>

          <template #footer>
            <span class="dialog-footer">
              <el-button @click="closeDialog">取消</el-button>
              <el-button type="primary" @click="sureDialog()">確定</el-button>
            </span>
          </template>
        </el-dialog>
  </div>

</template>

<script lang="ts">
import { type } from "os";
import { defineComponent ,ref} from "vue";
import { ElForm, ElMessage } from "element-plus";
type FormInstance = InstanceType<typeof ElForm>;
export default defineComponent({
  data() {
    return {
      stageOptionData: [
        {
          id: 1,
          name: "編譯",
          value: "ifBuild",
        }, {
          id: 2,
          name: "靜態(tài)檢查",
          value: "ifCodeCheck",
        }, {
          id: 3,
          name: "單元測試",
          value: "ifUT",
        }, {
          id: 4,
          name: "冒煙",
          value: "ifSmoke",
        },
      ],
      stageRules: {
        data: [
          {
            required: true,
            trigger: "change",
            message: "請選擇階段",
          },
        ],
      },
      activeNames : ref(['4']),
      stageAddVisible: false,
      stageDialogData:{
        data:''
      },
      // stageData:[],
     stageData: [
        {
          id:1,
          name:'初始化環(huán)境',
          children:[{
            id:2,
            'name':'靜態(tài)檢查'
          },
          {
            id:3,
            'name':'編譯'
          },
          ]
        },
        {
          id:4,
          name:'編譯',
          children:[{
            id:5,
            'name':'靜態(tài)檢查'
          },
          {
            id:6,
            'name':'冒煙'
          }
          ]
        },
          {
          id:7,
          name:'編譯2',
          children:[]
        },
          {
          id:8,
          name:'編譯3',
          children:[]
        },
      ],
      curArr:[] as any,//當前操作數組
      curType:'x',//當前操作的軸  "x" -x軸     "y" ---y軸
    };
  },
  created() {
  },
  mounted() {

  },
  unmounted() {
  },
  
  methods: {
    addStage(info,type){
        this.stageAddVisible = true;
        if(this.$refs.ruleFormRefStage){
          this.$refs.ruleFormRefStage.clearValidate();
      }
      console.log('info------',info);
      console.log('type------',type);
        this.curArr = info;
        this.curType = type;
    },
    deleteStage(info,type,fatherInfo?){
      console.log('info-----------------',info);
      let conTip = '是否刪除當前階段?';
      let $that = this;
       this.$layer.confirm(conTip, {
           async onSure () {
                if(type == 'x'){ //是外層
                    $that.stageData = $that.stageData.filter(function(item) {    return item.id != info.id});//刪除
                }else{ //是children
                      if(fatherInfo.children.length > 0){
                            let yOneDelInfo = fatherInfo.children;
                            yOneDelInfo = yOneDelInfo.filter(function(item) {  return item.id != info.id});
                            let targetIndex = $that.stageData.findIndex((itemTemp) => {
                                   return  itemTemp.id == fatherInfo.id
                            });
                            $that.stageData[targetIndex].children = yOneDelInfo;
                        }
                        
                }
              
            },
      });
    },
    closeDialog() {
      this.stageAddVisible = false;
      // 清除表單驗證提示信息
      if(this.$refs.ruleFormRefStage){
          this.$refs.ruleFormRefStage.clearValidate();
      }
      this.stageDialogData = {
         data: "",
      }
     
    },
    getPosition(number,type){
      let leftVal =  0;
      let topVal =  0;
      if(type == 'x'){
        leftVal =  140*number;
      }else if(type == 'y'){
        number = number + 1;
        topVal =  40*number;
      }
      let obj = {
        left: leftVal+'px',
        top: topVal+'px'
      }
      return obj;
    },
    mouseoverHandle(event){
        if(typeof event.target.className == 'object'){ //是刪除圖標
          return;
        }
        if(event.target.className.indexOf('item') === -1) {
          event.target.parentNode.className = `${event.target.parentNode.className } hover-btn`
          return
        }     
        event.target.className = `${event.target.className } hover-btn`
    },
   mouseoutHandle(event){
    if(typeof event.target.className == 'object'){ //是刪除圖標
      return;
    }
      if(event.target.className.indexOf('item') === -1) {
          event.target.parentNode.className =event.target.parentNode.className.replace('hover-btn', '')
          return
        }     
       event.target.className = event.target.className.replace('hover-btn', '')
   },
    sureDialog() {
          (this.$refs.ruleFormRefStage as FormInstance).validate((valid) => {
            if (valid) {
               console.log('this.stageDialogData=====22============---',this.stageDialogData);
              let curVal =   this.stageOptionData.filter((i)=>{
                      return i.name == this.stageDialogData.data;
                })
               if(this.curType =='x'){
                   this.curArr.push({
                      id: parseInt(Math.random() * 100000000000),
                      name: this.stageDialogData.data,
                      value:curVal[0]?.value,
                      children:[]
                  })
               }else{
                   this.curArr.push( {
                      id: parseInt(Math.random() * 100000000000),
                     value:curVal[0]?.value,
                      name: this.stageDialogData.data,
                  })
               }
                console.log('this.curArr=====333============---',this.curArr);
               this.stageAddVisible = false;
            
            }
      });
      
    },
  },
  
});
</script>


<style lang="scss" scoped>
.car-detail-view {
  .car-detail-title {
    background: #fff;
    padding: 0 10px;
    height: 50px;
    line-height: 50px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-radius: 4px;
    margin-bottom: 10px;
  }
  .detail-center {
    display: flex;
    height: calc(100% - 60px);
    flex-direction: column;
    background: #ffffff;
    padding: 10px;
    .stage-content{
          height: 400px;
          width: 100%;
          overflow: auto;
          position: relative;
          .item{
            width: 90px;
            height: 32px;
            background-color: #ededed;
            line-height: 32px;
            text-align: center;
            // border:1px dotted #ededed;
            color:#000000a6;
            border-radius: 5px;
            cursor: pointer;
            position: absolute;
            span:first-child{
              margin-right: 4px;
            }
            span.icon{
              vertical-align: middle;
            }
            i.el-icon{
              vertical-align: middle;
              font-size: 16px;
            }
            span.text-x::before{//水平線
              content: '';
              width: 50px;
              height: 0px;
              border-top:1px dotted #aaa;
              position: absolute;
              left: 90px;
              top: 16px;
            }
            span.text-y::after,
            span.text-x::after{//垂直線
                content: '';
                height: 50px;
                width: 0;
                border-left:1px dotted #aaa;
                position: absolute;
                left: 45px;
                top: 32px;
            }
          // &:hover{
          //     background-color:#1c3dd7;
          //     color: #ffffff;
          //   }
            .children{
              position: relative;
              width: 90px;
              height: 32px;
              line-height: 32px;
              text-align: center;
                background-color: #ededed;
              // border:1px dotted #1c3dd7;
              color:#000000a6;
              border-radius: 5px;
              cursor: pointer;
              &:hover{
                background-color:#1c3dd7;
                color: #ffffff;
              }
              //  &:hover  ~  .item{
              //      background-color: #E8EBFB;
              //      pointer-events: none;
              //      border: 1px solid #000;
              //  }
              
            }

          }
          .children.add-btn,
          .add-btn{
              background-color: #E8EBFB ;
              border:1px dotted #1c3dd7;
              color:#1c3dd7;
          }
          .hover-btn{
              background-color:#1c3dd7;
              color: #ffffff;
          }
    }  
 
  }

}
</style>

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末蜓席,一起剝皮案震驚了整個濱河市避消,隨后出現的幾起案子,更是在濱河造成了極大的恐慌缘滥,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件于宙,死亡現場離奇詭異摩梧,居然都是意外死亡,警方通過查閱死者的電腦和手機卖漫,發(fā)現死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門费尽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人羊始,你說我怎么就攤上這事旱幼。” “怎么了突委?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵柏卤,是天一觀的道長。 經常有香客問我匀油,道長缘缚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任敌蚜,我火速辦了婚禮桥滨,結果婚禮上,老公的妹妹穿的比我還像新娘弛车。我一直安慰自己齐媒,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布纷跛。 她就那樣靜靜地躺著喻括,像睡著了一般。 火紅的嫁衣襯著肌膚如雪忽舟。 梳的紋絲不亂的頭發(fā)上双妨,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天淮阐,我揣著相機與錄音,去河邊找鬼刁品。 笑死泣特,一個胖子當著我的面吹牛,可吹牛的內容都是我干的挑随。 我是一名探鬼主播状您,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼兜挨!你這毒婦竟也來了膏孟?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤拌汇,失蹤者是張志新(化名)和其女友劉穎柒桑,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體噪舀,經...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡魁淳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了与倡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片界逛。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖纺座,靈堂內的尸體忽然破棺而出息拜,到底是詐尸還是另有隱情,我是刑警寧澤净响,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布少欺,位于F島的核電站,受9級特大地震影響别惦,放射性物質發(fā)生泄漏狈茉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一掸掸、第九天 我趴在偏房一處隱蔽的房頂上張望氯庆。 院中可真熱鬧,春花似錦扰付、人聲如沸堤撵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽实昨。三九已至,卻和暖如春盐固,著一層夾襖步出監(jiān)牢的瞬間荒给,已是汗流浹背丈挟。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留志电,地道東北人曙咽。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像挑辆,于是被迫代替她去往敵國和親例朱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內容