Rumah  >  Artikel  >  hujung hadapan web  >  Bagaimana untuk menggunakan Vue untuk mencipta carta alir?

Bagaimana untuk menggunakan Vue untuk mencipta carta alir?

WBOY
WBOYasal
2023-06-25 09:16:433917semak imbas

Dengan perkembangan Internet, semakin banyak aplikasi memerlukan penghasilan carta alir, seperti carta aliran kerja, rajah litar, dsb. Sebagai rangka kerja bahagian hadapan yang sangat popular, Vue.js menyediakan interaktiviti dan kebolehselenggaraan yang sangat baik, jadi ia digunakan secara meluas untuk membina aplikasi carta alir yang kompleks.

Artikel ini akan memperkenalkan cara menggunakan Vue untuk melaksanakan pengeluaran carta alir, termasuk langkah berikut:

  1. Pasang kebergantungan yang diperlukan
  2. Tulis struktur komponen asas
  3. Laksanakan fungsi seret dan lepas
  4. Laksanakan talian sambungan
  5. melaksanakan penyuntingan nod
  6. Eksport Carta Aliran
  7. Memasang kebergantungan yang diperlukan

Pertama, kita perlu memasang perpustakaan boleh seret-boleh diubah saiz vue, yang merupakan pemalam Vue yang sangat mudah digunakan yang boleh merealisasikan seretan dan fungsi zum elemen. Kita boleh menggunakan pemasangan npm:
    npm install vue-draggable-resizable --save
  1. Tulis struktur komponen asas

Kita perlu menggunakan komponen Vue untuk melaksanakan penyuntingan carta alir. Kita perlu mencipta komponen Carta Alir yang mengandungi semua elemen carta alir. Setiap nod ialah komponen Nod yang mewakili satu langkah dalam carta alir. Talian sambungan ialah komponen Sambungan yang digunakan untuk menyambungkan nod yang berbeza.

Pertama, kita perlu mencipta komponen FlowChart abstrak dalam fail FlowChart.vue untuk mengandungi semua nod dan talian penyambung:

<template>
  <div class="flowchart">
    <div class="nodes">
      <!-- 组件插槽,用于插入节点 -->
      <slot name="nodes"></slot>
    </div>
    <svg class="connections">
      <!-- 组件插槽,用于插入连接线 -->
      <slot name="connections"></slot>
    </svg>
  </div>
</template>

<script>
export default {
  name: 'FlowChart'
}
</script>

Kami meletakkan nod dan talian penyambung dalam dua slot komponen FlowChart masing-masing.

Seterusnya, kita perlu mencipta komponen Nod dan Sambungan untuk mewakili nod dan garis sambungan carta alir:

Node.vue:

<template>
  <draggable-resizable :w="width" :h="height" :x="x" :y="y">
    <div class="node">
      <!-- 节点的内容 -->
      <div class="node-content">
        <slot></slot>
      </div>
    </div>
  </draggable-resizable>
</template>

<script>
import VueDraggableResizable from 'vue-draggable-resizable'

export default {
  name: 'Node',
  components: {
    VueDraggableResizable
  },
  props: {
    width: {
      type: Number,
      default: 100
    },
    height: {
      type: Number,
      default: 50
    },
    x: {
      type: Number,
      default: 0
    },
    y: {
      type: Number,
      default: 0
    }
  }
}
</script>

Connection.vue:

<template>
  <svg class="connection">
    <!-- SVG 路径元素,用于绘制连接线 -->
    <path :d="path"></path>
  </svg>
</template>

<script>
export default {
  name: 'Connection',
  props: {
    start: Object,
    end: Object
  },
  computed: {
    path () {
      // 计算连接线的路径
      const startX = this.start.x + this.start.width / 2
      const startY = this.start.y + this.start.height / 2
      const endX = this.end.x + this.end.width / 2
      const endY = this.end.y + this.end.height / 2
      return `M ${startX} ${startY} L ${endX} ${endY}`
    }
  }
}
</script>

Kami menggunakan komponen vue-draggable-resizable untuk implement Untuk menyeret dan menskala nod, lebar, tinggi, x, y dan atribut lain nod perlu dilalui. Garis penghubung dilukis menggunakan elemen laluan SVG, dan laluan perlu dikira berdasarkan kedudukan dan saiz nod.
  1. Laksanakan fungsi seret dan lepas

Untuk melaksanakan fungsi seret dan lepas nod, kita perlu menambah v-on:drag, v-on:dragstop dan v-on:resize event listener dalam komponen Nod . Mereka masing-masing sepadan dengan penyeretan, pengakhiran penyeretan dan saiz semula nod:

<draggable-resizable
  :w="width"
  :h="height"
  :x="x"
  :y="y"
  v-on:drag="onDrag"
  v-on:dragstop="onDragStop"
  v-on:resize="onResize"
>
  <!-- 节点的内容 -->
</draggable-resizable>

<script>
export default {
  name: 'Node',
  methods: {
    onDrag (pos) {
      // 拖拽事件处理函数
      this.$emit('move', {
        x: pos.x,
        y: pos.y
      })
    },
    onDragStop (pos) {
      // 结束拖拽事件处理函数
      this.$emit('endMove', {
        x: pos.x,
        y: pos.y
      })
    },
    onResize (size) {
      // 调整大小事件处理函数
      this.$emit('resize', {
        width: size.width,
        height: size.height
      })
    }
  }
}
</script>

Kami menghantar acara kepada komponen induk melalui kaedah $emit dalam fungsi pengendalian acara ini untuk mencapai kemas kini masa nyata kedudukan dan saiz nod. Dalam komponen FlowChart, kita perlu mendengar peristiwa ini dan mengemas kini maklumat nod:

<template>
  <div class="flowchart">
    <div class="nodes">
      <!-- 将节点插入到插槽中 -->
      <slot name="nodes"></slot>
    </div>
    <svg class="connections">
      <!-- 将连接线插入到插槽中 -->
      <slot name="connections"></slot>
      <!-- 鼠标跟随的连接线 -->
      <Connection v-if="showConnection"
                  :start="{x: start.x + start.width / 2, y: start.y + start.height / 2, width: start.width, height: start.height}"
                  :end="{x: end.x + end.width / 2, y: end.y + end.height / 2, width: end.width, height: end.height}"/>
    </svg>
  </div>
</template>

<script>
import Node from './Node.vue'
import Connection from './Connection.vue'

export default {
  name: 'FlowChart',
  components: {
    Node,
    Connection
  },
  data () {
    return {
      showConnection: false,
      start: null, // 起点节点
      end: null // 终点节点
    }
  },
  methods: {
    onNodeMove (node, pos) {
      // 节点拖拽时的事件处理函数
      node.x = pos.x
      node.y = pos.y
    },
    onNodeEndMove (node, pos) {
      // 节点结束拖拽时的事件处理函数
      node.x = pos.x
      node.y = pos.y
      this.showConnection = false
      this.start = null
      this.end = null
    },
    onNodeResize (node, size) {
      // 节点调整大小时的事件处理函数
      node.width = size.width
      node.height = size.height
    },
    connectNodes (start, end) {
      // 连接两个节点
      this.showConnection = true
      this.start = start
      this.end = end
    }
  }
}
</script>

Kami telah mentakrifkan tiga fungsi pengendalian acara onNodeMove, onNodeEndMove dan onNodeResize untuk bertindak balas kepada penyeretan, penamatan seretan dan saiz semula nod. Fungsi connectNodes digunakan untuk menyambung dua nod.
  1. Melaksanakan talian sambungan

Dalam komponen FlowChart, kami mentakrifkan pembolehubah showConnection dan dua pembolehubah bermula dan tamat untuk menyimpan maklumat talian sambungan. Kami perlu mengemas kini maklumat ini melalui acara tetikus untuk menarik garis sambungan.

Pertama, kita perlu menambah mendengar untuk acara v-on:mousedown dan v-on:mouseup dalam komponen Node. Peristiwa ini digunakan untuk mengesan sama ada pengguna telah memilih nod:

<draggable-resizable
  :w="width"
  :h="height"
  :x="x"
  :y="y"
  v-on:drag="onDrag"
  v-on:dragstop="onDragStop"
  v-on:resize="onResize"
  v-on:mousedown="onMouseDown"
  v-on:mouseup="onMouseUp"
>
  <!-- 节点的内容 -->
</draggable-resizable>

<script>
export default {
  name: 'Node',
  methods: {
    ...
    onMouseDown () {
      // 鼠标按下时选中当前节点
      this.$emit('select', this)
    },
    onMouseUp () {
      // 鼠标松开时取消选中
      this.$emit('unselect')
    }
  }
}
</script>

Kami menghantar acara pilih kepada komponen induk dalam fungsi pengendali acara onMouseDown untuk memilih nod semasa. Dalam komponen FlowChart, kita perlu mendengar acara ini:

<template>
  <div class="flowchart">
    <div class="nodes">
      <!-- 将节点插入到插槽中 -->
      <slot name="nodes"></slot>
    </div>
    <svg class="connections">
      <!-- 将连接线插入到插槽中 -->
      <slot name="connections"></slot>
      <!-- 鼠标跟随的连接线 -->
      <Connection v-if="showConnection"
                  :start="{x: start.x + start.width / 2, y: start.y + start.height / 2, width: start.width, height: start.height}"
                  :end="{x: end.x + end.width / 2, y: end.y + end.height / 2, width: end.width, height: end.height}"/>
    </svg>
  </div>
</template>

<script>
import Node from './Node.vue'
import Connection from './Connection.vue'

export default {
  name: 'FlowChart',
  components: {
    Node,
    Connection
  },
  data () {
    return {
      showConnection: false,
      start: null, // 起点节点
      end: null // 终点节点
    }
  },
  methods: {
    ...
    onSelectNode (node) {
      // 选中节点时的事件处理函数
      if (this.start) {
        // 已选择起点,连接当前节点
        this.end = node
        this.connectNodes(this.start, this.end)
      } else {
        // 选择起点
        this.start = node
      }
    },
    onUnselectNode () {
      // 取消选中节点时的事件处理函数
      this.start = null
      this.end = null
      this.showConnection = false
    }
  }
}
</script>

Kami menentukan sama ada nod titik mula dipilih pada masa ini dalam fungsi pengendali acara onSelectNode, dan jika ya, sambungkan nod semasa, tetapkan nod semasa sebagai titik permulaan. Dalam pengendali acara onUnselectNode, nyahpilih nod dan tetapkan semula maklumat talian sambungan.
  1. Realisasikan penyuntingan nod

Untuk melaksanakan penyuntingan nod, kita perlu menambah butang edit dalam Node.vue dan mendengar acara kliknya:

<template>
  <draggable-resizable ...>
    <div class="node">
      <div class="node-content" v-on:click="$emit('edit')">
        <!-- 节点的内容 -->
      </div>
      <button class="edit-button" v-on:click="$emit('edit')">
        编辑
      </button>
    </div>
  </draggable-resizable>
</template>

<script>
export default {
  name: 'Node'
}
</script>

<style>
.edit-button {
  position: absolute;
  bottom: 5px;
  right: 5px;
}
</style>

Kemudian, dengar acara edit dalam FlowChart.vue, dan pilih Paparkan kotak input pada nod:

<template>
  <div class="flowchart">
    <div class="nodes">
      <!-- 将节点插入到插槽中 -->
      <slot name="nodes"></slot>
    </div>
    <svg class="connections">
      <!-- 将连接线插入到插槽中 -->
      <slot name="connections"></slot>
      <!-- 鼠标跟随的连接线 -->
      <Connection v-if="showConnection"
                  :start="{x: start.x + start.width / 2, y: start.y + start.height / 2, width: start.width, height: start.height}"
                  :end="{x: end.x + end.width / 2, y: end.y + end.height / 2, width: end.width, height: end.height}"/>
    </svg>

    <!-- 编辑区域 -->
    <div class="edit-panel" v-if="selectedNode">
      <h3>编辑节点</h3>
      <form v-on:submit.prevent="saveNode">
        <label for="node-label">节点名称</label>
        <input id="node-label" type="text" v-model="nodeLabel">
        <button type="submit">保存</button>
      </form>
    </div>
  </div>
</template>

<script>
export default {
  name: 'FlowChart',
  data () {
    return {
      showConnection: false,
      start: null, // 起点节点
      end: null, // 终点节点
      selectedNode: null, // 选中的节点
      nodeLabel: '' // 当前节点的标签
    }
  },
  methods: {
    ...
    onSelectNode (node) {
      // 选中节点时的事件处理函数
      if (this.start) {
        // 已选择起点,连接当前节点
        this.end = node
        this.connectNodes(this.start, this.end)
        this.selectedNode = null
      } else {
        // 选择起点
        this.start = node
      }
    },
    onUnselectNode () {
      // 取消选中节点时的事件处理函数
      this.start = null
      this.end = null
      this.showConnection = false
      this.selectedNode = null
    },
    onEditNode (node) {
      // 编辑节点时的事件处理函数
      this.selectedNode = node
      this.nodeLabel = node.$slots.default[0].text.trim()
    },
    saveNode () {
      // 保存节点编辑后的信息
      this.selectedNode.$slots.default[0].text = this.nodeLabel
      this.selectedNode = null
    }
  }
}
</script>

<style>
.edit-panel {
  position: absolute;
  top: 0;
  right: 0;
  width: 300px;
  height: 100%;
  background: #fff;
  padding: 20px;
  box-shadow: -1px 0 10px rgba(0, 0, 0, 0.3);
}
</style>

Kami menambah ini.selectedNode = null dalam fungsi pengendali acara onSelectNode untuk menyembunyikan kotak edit nod. Dalam pengendali acara onEditNode, kami menghantar acara edit kepada komponen induk untuk memaparkan kotak input untuk mengedit nod yang dipilih. Kami menyimpan maklumat yang disunting nod dalam fungsi pengendali acara saveNode.
  1. Eksport carta alir

Akhir sekali, kami boleh menambah butang eksport dalam FlowChart.vue untuk mengeksport carta alir semasa ke format JSON: 🎜
<template>
  <div class="flowchart">
    <div class="nodes">
      <!-- 将节点插入到插槽中 -->
      <slot name="nodes"></slot>
    </div>
    <svg class="connections">
      <!-- 将连接线插入到插槽中 -->
      <slot name="connections"></slot>
      <!-- 鼠标跟随的连接线 -->
      <Connection v-if="showConnection"
                  :start="{x: start.x + start.width / 2, y: start.y + start.height / 2, width: start.width, height: start.height}"
                  :end="{x: end.x + end.width / 2, y: end.y + end.height / 2, width: end.width, height: end.height}"/>
    </svg>

    <!-- 编辑区域 -->
    ...

    <!-- 导出按钮 -->
    <button class="export-button" v-on:click="exportFlowchart">导出</button>
  </div>
</template>

<script>
export default {
  name: 'FlowChart',
  methods: {
    ...
    exportFlowchart () {
      // 导出流程图
      const nodes = []
      const connections = []
      this.$slots.nodes.forEach(vnode => {
        const node = vnode.componentInstance
        nodes.push({
          x: node.x,
          y: node.y,
          width: node.width,
          height: node.height,
          label: node.$slots.default[0].text.trim()
        })
      })

Atas ialah kandungan terperinci Bagaimana untuk menggunakan Vue untuk mencipta carta alir?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn