refactor(nodes): reduce nodewrapper re-render

# What's changed?

* use v-model for computed pos
* remove computed from style and class getters
This commit is contained in:
Braks
2022-05-27 23:36:01 +02:00
parent 33127395b6
commit a65d85687d
2 changed files with 41 additions and 36 deletions
@@ -1,12 +1,12 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import { useVueFlow, useDrag } from '../../composables'
import { NodeComponent, SnapGrid } from '../../types'
import { NodeComponent, SnapGrid, XYZPosition } from '../../types'
import { NodeId } from '../../context'
import { getConnectedEdges, getHandleBounds, getXYZPos } from '../../utils'
const { id, type, name, draggable, selectable, connectable, snapGrid } = defineProps<{
const { id, type, name, draggable, selectable, connectable, snapGrid, ...props } = defineProps<{
id: string
modelValue: XYZPosition
draggable: boolean
selectable: boolean
connectable: boolean
@@ -15,6 +15,11 @@ const { id, type, name, draggable, selectable, connectable, snapGrid } = defineP
name: string
}>()
const emit = defineEmits(['update:modelValue'])
let computedPosition = $(useVModel(props, 'modelValue', emit))
provide(NodeId, id)
const {
@@ -95,7 +100,7 @@ onMounted(() => {
onBeforeUnmount(() => observer.stop())
watch(
[() => node.position, () => parentNode?.computedPosition, () => node.selected, () => parentNode?.selected],
[() => node.position, () => parentNode?.computedPosition],
([pos, parent]) => {
const xyzPos = {
...pos,
@@ -103,14 +108,14 @@ onMounted(() => {
}
if (parent) {
node.computedPosition = getXYZPos(parent, xyzPos)
computedPosition = getXYZPos(parent, xyzPos)
} else {
node.computedPosition = xyzPos
computedPosition = xyzPos
}
node.handleBounds = getHandleBounds(nodeElement.value, viewport.zoom)
},
{ deep: true, flush: 'post' },
{ immediate: true, deep: true, flush: 'post' },
)
})
@@ -160,35 +165,19 @@ const onSelectNode = (event: MouseEvent) => {
}
}
const getClass = computed(() => {
const extraClass = node.class instanceof Function ? node.class(node) : node.class
return [
'vue-flow__node',
`vue-flow__node-${name}`,
noPanClassName,
{
dragging,
selected: node.selected,
selectable,
},
extraClass,
]
})
const getClass = () => {
return node.class instanceof Function ? node.class(node) : node.class
}
const getStyle = computed(() => {
const getStyle = () => {
const styles = (node.style instanceof Function ? node.style(node) : node.style) || {}
const width = node.width instanceof Function ? node.width(node) : node.width
const height = node.height instanceof Function ? node.height(node) : node.height
if (width) styles.width = typeof width === 'string' ? width : `${width}px`
if (height) styles.height = typeof height === 'string' ? height : `${height}px`
return {
zIndex: node.computedPosition.z,
transform: `translate(${node.computedPosition.x}px,${node.computedPosition.y}px)`,
pointerEvents: selectable || draggable ? 'all' : 'none',
...styles,
} as CSSProperties
})
return styles
}
</script>
<script lang="ts">
@@ -201,8 +190,23 @@ export default {
<template>
<div
ref="nodeElement"
:class="getClass"
:style="getStyle"
:class="[
'vue-flow__node',
`vue-flow__node-${name}`,
noPanClassName,
{
dragging,
selected: node.selected,
selectable,
},
getClass(),
]"
:style="{
zIndex: node.computedPosition.z ? node.computedPosition.z : node.selected ? 1000 : 0,
transform: `translate(${node.computedPosition.x}px,${node.computedPosition.y}px)`,
pointerEvents: selectable || draggable ? 'all' : 'none',
...getStyle(),
}"
:data-id="node.id"
@mouseenter="onMouseEnter"
@mousemove="onMouseMove"
@@ -23,9 +23,9 @@ const selectable = (s?: boolean) => (typeof s === 'undefined' ? elementsSelectab
const connectable = (c?: boolean) => (typeof c === 'undefined' ? nodesConnectable : c)
const hasSnapGrid = (sg?: SnapGrid) => (sg ?? snapToGrid ? snapGrid : undefined)
const getType = (node: GraphNode) => {
const name = node.type || 'default'
let nodeType = node.template ?? getNodeTypes[name]
const getType = (type?: string, template?: GraphNode['template']) => {
const name = type || 'default'
let nodeType = template ?? getNodeTypes[name]
const instance = getCurrentInstance()
if (typeof nodeType === 'string') {
@@ -40,7 +40,7 @@ const getType = (node: GraphNode) => {
const slot = slots?.[`node-${name}`]
if (!slot?.({})) {
console.warn(`[vueflow]: Node type "${node.type}" not found and no node-slot detected. Using fallback type "default".`)
console.warn(`[vueflow]: Node type "${type}" not found and no node-slot detected. Using fallback type "default".`)
return false
}
@@ -60,7 +60,8 @@ export default {
v-for="node of getNodes"
:id="node.id"
:key="node.id"
:type="getType(node)"
v-model="node.computedPosition"
:type="getType(node.type, node.template)"
:name="node.type || 'default'"
:draggable="draggable(node.draggable)"
:selectable="selectable(node.selectable)"