Vue3+X6流程图实现数据双向绑定详解

 更新时间:2024年03月12日 08:43:25   作者:阿赛工作室  
这篇文章主要为大家详细介绍了Vue3如何结合X6流程图实现数据双向绑定,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

代码很简单,看看就可以了,不用多说。

定义组件:实现html节点与数据初始化、更新

<script setup lang="ts">
import { Graph, Shape } from "@antv/x6";
import { onMounted, reactive, ref, watch } from "vue";
import useFlowModel from "./useFlowModel";
import flowdata from "./flowdata";

const container: any = ref(null);

Shape.HTML.register({
  shape: "custom-html",
  effect: ["data"],
  html(cell: any) {
    const { bgcolor, label } = cell.getData();
    return `<div style="background:${bgcolor};width:100%;height:100%;">${label}</div>`;
  },
});

const flowModel: any = reactive({
  graph: null,

  datatype: 0,
  modeldata: flowdata,
});
const { graphToModelData, modelDataToGraph, addNode, addNodeData } =
  useFlowModel(flowModel);

onMounted(() => {
  flowModel.graph = new Graph({
    container: container.value,
    // 设置画布背景颜色
    background: {
      color: "#F2F7FA",
    },
    height: 300,
    width: 600,
    grid: {
      visible: true,
      type: "doubleMesh",
      args: [
        {
          color: "#eee", // 主网格线颜色
          thickness: 1, // 主网格线宽度
        },
        {
          color: "#ddd", // 次网格线颜色
          thickness: 1, // 次网格线宽度
          factor: 4, // 主次网格线间隔
        },
      ],
    },
  });

  flowModel.graph.fromJSON(flowModel.modeldata); // 渲染元素
  flowModel.graph.centerContent(); // 居中显示

  flowModel.graph.on("cell:changed", (val: any) => {
    graphToModelData(val);
  });

  watch(
    () => flowModel.modeldata.cells.map((el: any) => JSON.stringify(el.data)),
    (newVal, oldVal) => {
      modelDataToGraph(newVal, oldVal);
    },
    { deep: true }
  );
});
</script>

<template>
  <template
    v-if="flowModel.modeldata?.cells && flowModel.modeldata?.cells[0]?.position"
  >
    <input type="number" v-model="flowModel.modeldata.cells[0].position.x" />
    <input type="text" v-model="flowModel.modeldata.cells[0].data.label" />
    <input type="text" v-model="flowModel.modeldata.cells[0].data.bgcolor" />
  </template>
  【{{ flowModel.modeldata?.cells && flowModel.modeldata?.cells[0].position }}】

  <button @click="addNode()">加G</button>
  <button @click="addNodeData()">加A</button>
  <button
    @click="console.log(666.1001, flowModel.modeldata.cells[0].x, flowModel)"
  >
    实时
  </button>
  <div id="container" ref="container"></div>
  <div class="as-show-model">{{ flowModel.modeldata }}</div>
</template>

<style scoped>
html,
body {
  margin: 0;
  padding: 0;
}
.as-show-model {
  display: inline-block;
  white-space: pre-wrap;
  overflow: auto;
  height: 300px;
  width: 300px;
}
.custom-html {
  outline: 1px dashed bisque;
}
#container {
  display: inline-block;
  background-color: rgb(248, 255, 240);
  margin-right: 8px;
  margin-left: 8px;
  border-radius: 5px;
  box-shadow: 0 12px 5px -10px rgb(0 0 0 / 10%), 0 0 4px 0 rgb(0 0 0 / 10%);
}
</style>

基本函数处理

export default (flowModel: any) => {
  function modelDataToGraph(newVal: any, oldVal: any) {
    // console.log(666.333, oldVal, newVal);
    if (flowModel.datatype) {
      flowModel.datatype = 0;
    } else if (
      !oldVal?.length ||
      !newVal?.length ||
      oldVal?.length !== newVal?.length
    ) {
      flowModel.graph.fromJSON(flowModel.modeldata);
    } else {
      const nowCells: any = flowModel.graph.getCells();
      newVal.forEach((el: any, index: number) => {
        if (!oldVal.includes(el)) {
          flowModel.datatype = 2;
          nowCells[index].setProp({
            data: JSON.parse(el),
          });
        }
      });
    }
  }

  function graphToModelData(val: any) {
    // const { cell, options } = val;
    if (flowModel.datatype) {
      flowModel.datatype = 0;
    } else {
      flowModel.datatype = 1;
      flowModel.modeldata = flowModel.graph.toJSON();
    }
  }

  function addNodeData() {
    flowModel.modeldata.cells.push({
      position: {
        x: 30,
        y: 40,
      },
      size: {
        width: 100,
        height: 40,
      },
      data: {
        bgcolor: "#8f8f8f",
        label: "我是节点",
        color: "#333232",
        a: { B: 1 },
      },
      attrs: {
        text: {
          text: "我是节点",
        },
        body: {
          stroke: "#8f8f8f",
          strokeWidth: 1,
          fill: "#fff",
          rx: 6,
          ry: 6,
        },
      },
      visible: true,
      shape: "custom-html",
      id: "node1" + Date.now(),
      zIndex: 1,
    });
  }
  function addNode() {
    flowModel.graph.addNode({
      shape: "custom-html",
      x: 60,
      y: 100,
      width: 80,
      height: 40,
      data: {
        bgcolor: "#8f8f8f",
        label: "我是节点",
      },
    });
  }

  return { graphToModelData, modelDataToGraph, addNode, addNodeData };
};

演示数据

export default {
  cells: [
    {
      position: {
        x: 30,
        y: 40,
      },
      size: {
        width: 120,
        height: 40,
      },
      data: {
        bgcolor: "#8f8f8f",
        label: "我是节点",
        color: "#333232",
        a: { B: 1 },
      },
      attrs: {},
      visible: true,
      shape: "custom-html",
      id: "node1",
      zIndex: 1,
    },
    {
      position: {
        x: 160,
        y: 180,
      },
      size: {
        width: 111,
        height: 40,
      },
      attrs: {
        text: { text: "世界你好" },
        body: {
          stroke: "#8f8f8f",
          strokeWidth: 1,
          fill: "#fff",
          rx: 6,
          ry: 6,
        },
      },
      visible: true,
      shape: "rect",
      id: "node2",
      zIndex: 1,
    },
    {
      position: {
        x: 190,
        y: 100,
      },
      size: {
        width: 160,
        height: 40,
      },
      data: {
        bgcolor: "#8f8f8f",
        label: "my test",
        color: "#333232",
        a: { B: 1 },
      },
      attrs: {},
      visible: true,
      shape: "custom-html",
      id: "node3",
      zIndex: 1,
    },
    {
      shape: "edge",
      attrs: {
        label: {
          text: "x6",
        },
        line: {
          stroke: "#8f8f8f",
          strokeWidth: 1,
        },
      },
      id: "0d9f0031-f018-413c-9631-1cd21d2f8c1f",
      source: {
        cell: "node1",
      },
      target: {
        cell: "node2",
      },
      labels: [
        {
          attrs: {
            label: {
              text: "x6",
            },
          },
        },
      ],
      zIndex: 1,
    },
  ],
};

以上就是Vue3+X6流程图实现数据双向绑定详解的详细内容,更多关于Vue3数据双向绑定的资料请关注脚本之家其它相关文章!

相关文章

  • vue封装一个简单的div框选时间的组件的方法

    vue封装一个简单的div框选时间的组件的方法

    这篇文章主要介绍了vue封装一个简单的div框选时间的组件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • Vue动态路由路径重复及刷新丢失页面问题的解决

    Vue动态路由路径重复及刷新丢失页面问题的解决

    这篇文章主要介绍了Vue动态路由路径重复及刷新丢失页面问题的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • 分析 Vue 中的 computed 和 watch 的区别

    分析 Vue 中的 computed 和 watch 的区别

    这篇文章分析 Vue 的 computed 和 watch 的区别,computed 用来监控自己定义的变量,页面上可直接使用。watch 是监测 Vue 实例上的数据变动,通俗地讲,就是检测 data 内声明的数据,需要的朋友可以参考一下
    2021-09-09
  • 详解Vue新增内置组件的使用

    详解Vue新增内置组件的使用

    这篇文章主要为大家介绍了Vue新增内置组件的使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • proxy代理不生效以及vue config.js不生效解决方法

    proxy代理不生效以及vue config.js不生效解决方法

    在开发Vue项目过程中,使用了Proxy代理进行数据劫持,但是在实际运行过程中发现代理并没有生效,也就是说数据并没有被劫持,这篇文章主要给大家介绍了关于proxy代理不生效以及vue config.js不生效解决方法的相关资料,需要的朋友可以参考下
    2023-11-11
  • 深入探究Vue中探究组合式API的奥秘

    深入探究Vue中探究组合式API的奥秘

    Vue 3中引入了组合式API,它是一种新的代码组织方式,旨在让开发者更灵活地组织和重用Vue组件的逻辑,下面我们就来学习一下Vue中常见组合式API的使用吧
    2023-11-11
  • vue router点击打开新的标签页的方法(最新推荐)

    vue router点击打开新的标签页的方法(最新推荐)

    vue router点击打开新的标签页的方法,只需要在router-link中加入target="_blank"即可在新的页面打开标签,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2023-10-10
  • 浅析vue中的组件传值

    浅析vue中的组件传值

    这篇文章主要介绍了浅析vue中的组件传值,文章基于vue的相关资料展开对主题的详细介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-04-04
  • 对vue事件的延迟执行实例讲解

    对vue事件的延迟执行实例讲解

    今天小编就为大家分享一篇对vue事件的延迟执行实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • VNode虚拟节点实例简析

    VNode虚拟节点实例简析

    这篇文章主要介绍了VNode虚拟节点,结合实例形式分析了VNode虚拟节点的基本功能、原理与实现方法,需要的朋友可以参考下
    2023-06-06

最新评论