From 5e50eb9eb82571d22e0a2f1a2fe985addf7efe18 Mon Sep 17 00:00:00 2001 From: Benjamin Canac Date: Mon, 5 Jun 2023 11:17:28 +0200 Subject: [PATCH] fix: use `cloneVNode` when altering props in render functions Resolves #252 https://vuejs.org/api/render-function.html#clonevnode --- .../components/elements/AvatarGroup.ts | 12 +++++----- .../components/elements/ButtonGroup.ts | 22 ++++++++++--------- src/runtime/components/forms/FormGroup.ts | 14 +++++++----- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/runtime/components/elements/AvatarGroup.ts b/src/runtime/components/elements/AvatarGroup.ts index b5062fcb..fab2a558 100644 --- a/src/runtime/components/elements/AvatarGroup.ts +++ b/src/runtime/components/elements/AvatarGroup.ts @@ -1,4 +1,4 @@ -import { h, computed, defineComponent } from 'vue' +import { h, cloneVNode, computed, defineComponent } from 'vue' import type { PropType } from 'vue' import { defu } from 'defu' import { classNames, getSlotsChildren } from '../../utils' @@ -39,18 +39,20 @@ export default defineComponent({ const max = computed(() => typeof props.max === 'string' ? parseInt(props.max, 10) : props.max) const clones = computed(() => children.value.map((node, index) => { + const vProps: any = {} + if (!props.max || (max.value && index < max.value)) { if (props.size) { - node.props.size = props.size + vProps.size = props.size } - node.props.class = node.props.class || '' - node.props.class += ` ${classNames( + vProps.class = node.props.class || '' + vProps.class += ` ${classNames( ui.value.ring, ui.value.margin )}` - return node + return cloneVNode(node, vProps) } if (max.value !== undefined && index === max.value) { diff --git a/src/runtime/components/elements/ButtonGroup.ts b/src/runtime/components/elements/ButtonGroup.ts index eaf9c4f1..fcf70678 100644 --- a/src/runtime/components/elements/ButtonGroup.ts +++ b/src/runtime/components/elements/ButtonGroup.ts @@ -1,4 +1,4 @@ -import { h, computed, defineComponent } from 'vue' +import { h, cloneVNode, computed, defineComponent } from 'vue' import type { PropType } from 'vue' import { defu } from 'defu' import { getSlotsChildren } from '../../utils' @@ -44,28 +44,30 @@ export default defineComponent({ }[ui.value.rounded])) const clones = computed(() => children.value.map((node, index) => { + const vProps: any = {} + if (props.size) { - node.props.size = props.size + vProps.size = props.size } - node.props.class = node.props.class || '' - node.props.class += ' !shadow-none' - node.props.ui = node.props.ui || {} - node.props.ui.rounded = '' + vProps.class = node.props.class || '' + vProps.class += ' !shadow-none' + vProps.ui = node.props.ui || {} + vProps.ui.rounded = '' if (index === 0) { - node.props.ui.rounded = rounded.value.left + vProps.ui.rounded = rounded.value.left } if (index > 0) { - node.props.class += ' -ml-px' + vProps.class += ' -ml-px' } if (index === children.value.length - 1) { - node.props.ui.rounded = rounded.value.right + vProps.ui.rounded = rounded.value.right } - return node + return cloneVNode(node, vProps) })) return () => h('div', { class: [ui.value.wrapper, ui.value.rounded, ui.value.shadow] }, clones.value) diff --git a/src/runtime/components/forms/FormGroup.ts b/src/runtime/components/forms/FormGroup.ts index f94c140e..4912f7da 100644 --- a/src/runtime/components/forms/FormGroup.ts +++ b/src/runtime/components/forms/FormGroup.ts @@ -1,4 +1,4 @@ -import { h, computed, defineComponent } from 'vue' +import { h, cloneVNode, computed, defineComponent } from 'vue' import type { PropType } from 'vue' import { defu } from 'defu' import { getSlotsChildren } from '../../utils' @@ -53,18 +53,20 @@ export default defineComponent({ const children = computed(() => getSlotsChildren(slots)) const clones = computed(() => children.value.map((node) => { + const vProps: any = {} + if (props.error) { - node.props.oldColor = node.props.color - node.props.color = 'red' + vProps.oldColor = node.props.color + vProps.color = 'red' } else { - node.props.color = node.props.oldColor + vProps.color = vProps.oldColor } if (props.name) { - node.props.name = props.name + vProps.name = props.name } - return node + return cloneVNode(node, vProps) })) return () => h('div', { class: [ui.value.wrapper] }, [