Closed ZionDoki closed 4 years ago
目前是不可以的,只能用普通的 DOM 标签。
我的解决思路:
出现的问题: zoom、drag时会重绘,组件状态会丢失
<template lang="pug">
div.graph(ref="main") hello,word
</template>
<script>
import Vue from 'vue'
import G6 from '@antv/g6'
import Panel from './Panel'
// recursion treeData
function _recursion(memo, item) {
const ins = new (Vue.extend(Panel))({
propsData: {
detail: item
}
}).$mount()
memo[item.id] = ins
if (item.children) {
item.children.reduce(_recursion, memo)
}
return memo
}
function _generateDOMId(id) {
return `panel-item${id}`
}
G6.registerNode(
'dom-node',
{
draw: (cfg, group) => {
const {
size: [w, h],
domId,
children,
...rest
} = cfg
const rectConfig = {
...rest,
children,
x: 0,
y: 0,
width: w,
height: h
}
const rect = group.addShape('dom', {
attrs: {
...rectConfig,
html: `<div id="${domId}"></div>`
}
})
return rect
}
},
'single-node'
)
export default {
name: 'MyGraph',
props: {
data: {
type: Array,
default: () => []
}
},
data() {
return {
graphIns: null
}
},
computed: {
panelInsMap(vm) {
return vm.data.reduce(_recursion, {})
}
},
mounted() {
const rect = this.$refs.main.getBoundingClientRect()
const graph = new G6.TreeGraph({
container: this.$refs.main,
renderer: 'svg',
animate: false,
width: rect.width,
height: rect.height,
defaultNode: {
type: 'dom-node'
}
})
graph.node(cfg => {
return {
...cfg,
domId: _generateDOMId(cfg.id)
}
})
graph.on('afterlayout', this.appendVueInsToGNode)
graph.on('dragend', this.appendVueInsToGNode)
graph.on('wheelzoom', this.appendVueInsToGNode)
this.graphIns = graph
},
beforeDestroy() {
if (this.graphIns) {
this.graphIns.off('afterlayout', this.appendVueInsToGNode)
this.graphIns.off('dragend', this.appendVueInsToGNode)
this.graphIns.off('wheelzoom', this.appendVueInsToGNode)
this.graphIns.destroy()
}
// destroy VueIns
Object.values(this.panelInsMap).forEach(ins => {
ins.$destroy()
})
},
methods: {
appendVueInsToGNode() {
for (let id in this.panelInsMap) {
const ins = this.panelInsMap[id]
const container = document.querySelector(`#${_generateDOMId(id)}`)
container && container.appendChild(ins.$el)
}
}
},
watch: {
data: {
handler(val) {
const { graphIns } = this
if (graphIns) {
graphIns.clear()
graphIns.data(val[0])
graphIns.render()
}
},
immediate: true
}
}
}
</script>
请问,自定义
dom
节点有办法使用React
或者Vue
组件么?