首页 > 其他分享 >「AntV」X6 自定义vue节点(vue3)

「AntV」X6 自定义vue节点(vue3)

时间:2024-06-03 15:13:03浏览次数:23  
标签:node vue 自定义 AntV click 点击 事件 节点

官方文档

本篇文档只讲解vue3中如何使用,vue2的可以参考下官方文档

安装插件

@antv/x6-vue-shape

添加vue组件

既然使用vue节点,那么我们就需要准备一个vue的组件,这个组件就是节点的一些样式,根据你们的ui自行写代码即可

<template>
  <div>节点名称</div>
  <div>节点描述</div>
  ……
</template>

注册vue节点

  1. 导入vue节点注册插件

import { register, getTeleport } from '@antv/x6-vue-shape';

  1. 注册节点
register({
  shape: 'custom-vue-node',
  width: 'auto',
  height: 104,
  component: vueNode // 这个就是你定义的vue组件
});
  1. 添加传送门
import { getTeleport } from '@antv/x6-vue-shape';
const TeleportContainer = defineComponent(getTeleport());

// template 中添加标签,和你的画布容器平级
<div id="graphDom"></div>
<TeleportContainer />
  1. 使用
  const node = graph.createNode({
    shape: 'custom-vue-node',
    width: 100,
    height: 104,
    label: data?.name,
    id: data?.id,
    // 所有节点的数据源头都在这里设置,需要哪些字段自行添加即可
    data: {
      name: data?.name, // 节点的名称
      img: data?.img || remoteImgUrl.value, // 图标
      desc: data?.dataNum || 0, // 总数据描述
      ……
    },
    /**
     * 连接桩位置判断逻辑
     * 1、数据源类型的连接桩只显示右侧
     * 2、算子类型的连接桩显示左右两侧
     * 3、算子类型-关联回填的连接桩显示左侧
     */
    ports: {
      ...port
    }
  });

节点内部监听数据变化

const getNodeData = inject('getNode');
onMounted(() => {
  const currentNode = getNodeData();
    // 监听当前节点数据发生了变化
  currentNode.on('change:data', ({ current }) => {
    console.log('节点数据是否发生变化了 >>>', current);
  });
})

vue节点拖拽的时候报错?

image.png
检查你的vue组件是否是这种结构

<template>
  <div>内容:{{ dataNode.name }}</div>
  <n-badge>
    <n-avatar :src="vueIco"></n-avatar>
  </n-badge>
</template>

需要改成下面这种的结构(需要用根节点进行包裹)

<div>
  <div>内容:{{ dataNode.name }}</div>
  <n-badge>
    <n-avatar :src="vueIco"></n-avatar>
  </n-badge>
</div>

节点事件和vue节点内的click事件冲突问题

场景

因为我用的是vue类型的节点,所以这里就按照vue节点来进行讲解,其它的节点(React、Angular、Html)这些都是通用的。

在vue节点内部的某个元素上需要执行一个点击事件,但是在执行本事件的时候不能去触发node:click的事件、在执行node:click事件的时候不能触发vue节点的点击事件,也就是两边的事件都是独立的,谁也不能影响谁,而且vue节点内的点击事件在点击的时候还得获取当前节点信息

踩坑方案1

直接给vue的点击事件添加stop修饰符,阻止事件传递,然后在node:click的时候再阻止下,但是结果下来确是不行……

// vue节点的事件
@click.stop = test

// 父页面的节点节点事件
graph.on('node:click',{e} => {
  e.stopPropagation()
})

踩坑方案2

采用群里小伙伴的方案,阻止节点鼠标按下或者鼠标抬起的事件,这样可以实现在点击vue节点的时候不触发节点本身的node:click事件,虽然可以实现阻止的功能,但是不好操作节点的数据,我是需要获取当前节点的数据的

终极解决方案

通过获取click事件的点击区域进行判断,如果是点击了vue节点内的点击事件区域,就直接在node:click的时候阻止掉就行了

graph.on('node:click',{e} => {
  // 判断target的className或者id,或者你定义的一些自定义属性,
  // 反正只要你能知道当前点击的区域是属于谁的就行
  // 我在vue节点点击事件的标签上加了个class
  if(e.target.className == 'cu-class') return
})

vue节点数据如何反向传递给父组件(vue3)?

提的issues:https://github.com/antvis/X6/issues/4323 (这里面有vue2的解决方案)

这个问题还待解决,官方暂时没有任何答复,短期内只能根据我的业务需求用野路子实现,如果有其它的可以留言你的需求

场景

vue节点内部有一个复选框,用于勾选节点,选中后要给当前节点添加一个是否选中的属性,由于节点的数据更新只能在父页面进行更新,所以必须得把复选框绑定的值传递给父页面

解决方案1

这个方案属于野路子,不是很灵活,如果不是复选框那基本凉凉了

// vue节点内正常写复选框绑定的逻辑
const checked2 = ref(false);
<el-checkbox v-model="checked2" size="large" @change="checkChange"></el-checkbox>



// 父组件监听节点的点击事件
graph.on('node:click',({e,node}) => {
    let state = node.data.checkState ?? false;
  // 这个判断是为了解决复选框的点击事件和节点的点击事件冲突的问题
    if (e.target.className == 'el-checkbox__inner') {
      // 给节点添加一个checkState属性,标识是否选中
      node.updateData({ checkState: !state }, { ignoreHistory: true });
      return;
    }
})


// 最后点击保存按钮的时候获取下节点checkState为true的数据
const save = () => {
  const allNodes = graph.getNodes();
  // 我这里是取的id属性,如果你们需要其它的可以自行组装
  checkedOps.value = allNodes.filter(item => item.data.checkState).map(item => item.id);
  console.log('checkedOps >>>', checkedOps.value); 
}

解决方案2

这个方案就可以随便玩了,不再局限于我自己的需求,如果还要在节点上加其它的控件都可以完美的把数据传递到父组件,其灵感来源于github的小伙伴qw123gz,问官方交流群的群主,问了半天也没有给出方案……

子组件添加emit事件

<el-checkbox v-model="checked2" size="large" @change="checkChange"></el-checkbox>


const checked2 = ref(false);
const emits = defineEmits(['getCheckVal']);
const checkChange = val => {
  emits('getCheckVal', val);
};

父组件改造注册vue节点的代码

register({
  shape: 'custom-vue-node',
  width: 'auto',
  height: 104,
  // component: vueNode   这个是官方提供的注册方式
  component: {
    // 使用vue3的render渲染组件,并添加自定义事件
    render() {
      return h(vueNode, {
        // 事件名称前面必须添加 `on`
        onGetCheckVal: val => getMyCheckVal(val)
      });
    }
  }
});

至此,数据反向传递就完成了,至于怎么使用传递过来的数据就看你们的业务需求了


关系图谱可视化
AntV X6开发实践:踩过的坑与解决方案

标签:node,vue,自定义,AntV,click,点击,事件,节点
From: https://www.cnblogs.com/sxdpanda/p/18228916

相关文章

  • Vue 3 中实现引导页
     Vue 3中实现引导页五秒后自动进入首页,并在进入首页时检查用户ID的逻辑使用组合式API(setup)使用VueRouter进行页面导航在首页组件中检查用户ID如果无用户ID,导航回登录页面1.设置引导页组件<template><transitionname="fade"><divv-if="showSplash">......
  • Vue3.0+typescript+Vite+Pinia+Element-plus搭建vue3框架!
    使用Vite快速搭建脚手架命令行选项直接指定项目名称和想要使用的模板,Vite+Vue项目,运行(推荐使用yarn)#npm6.xnpminitvite@latestmy-vue-app--templatevue#npm7+,需要额外的双横线:npminitvite@latestmy-vue-app----templatevue#yarnyarncreatevite......
  • Vue3简单项目流程分享——工作室主页
    Vue3简单项目流程分享——工作室主页零、写在最前以下是项目相关的一些链接:源代码GitHub仓库(需要魔法上网):仓库网页示例(需要魔法上网):网页示例UI图(来源@设计师杨贺):MasterGo主页补充:由于时间关系,该网页没有适配手机端,最佳展示效果为网页端1440p宽度。如果你想要运行源代码:......
  • vue3异步组件
    vue2//定义一个异步组件constAsyncComponent=()=>({//需要加载的组件(应该是一个Promise)component:import('./MyComponent.vue'),//加载中应当渲染的组件loading:LoadingComponent,//出错时渲染的组件error:ErrorComponent,//渲染loadin......
  • vue-elementui中el-table跨页选择和v-if导致列错乱/选择框无法显示
    在vue-elementui中使用el-table,当type="selection"的时候,分页数据进行不同页跳转选择需要这种功能的时候我们需要在el-table的标签上为每个el-table-column都创建一个id;所以就用到了row-key="id"这个属性;然后我们就需要在el-table-column为type="selection"添加一个属性reserve......
  • vue 代码块
    一、代码块vue2.0安装依赖$npminstallvue-highlightjshighlight.js--save配置导入main.jsimportVueHighlightJSfrom'vue-highlightjs';import'highlight.js/styles/default.css';//选择你想要的样式//使用插件Vue.use(VueHighlightJS);具体使用<t......
  • vue 动态表单
    一、动态表单数据集1、原始数据集varjson="[{\"key\":\"id\",\"text\":\"id\"},{\"key\":\"name\",\"text\":\"姓名\"},{......
  • Vue.js - 生命周期与工程化开发【0基础向 Vue 基础学习】
    文章目录Vue的生命周期Vue生命周期的四个阶段Vue生命周期函数(钩子函数工程化开发&脚手架VueCLI**开发Vue的两种方式:**脚手架目录文件介绍项目运行流程组件化开发&根组件App.vue文件(单文件组件)的三个组成部分普通组件的注册使用局部注册的方法全局注册的方法......
  • IDEA自定义配置注释模板,让你看起来更加专业!!!
    一:类注释我们先来康康成果:在以上的代码中我们可以看到只要创建一个类,idea自动会给你补充注释消息,有作者信息和创建时间关于模板参数代码我已经放到下面了:/***@author:dlwlrma*@data${YEAR}年${MONTH}月${DAY}日${TIME}*/ 使用方法:打开IDEA的Settings,点击Edi......
  • 为什么选择 Vue 3?
    专栏目录《Vue3基础》文章目录专栏目录前言一、Vue是什么?Vue是什么?Vue的三个特点1、组件化架构2、响应式编程3、学习成本低Vue生态适用场景横向比较二、为什么选择Vue3?Vue2.x和Vue3.x的主要区别Vue3升级指南总结前言随着互联网行业的不断发展,......