fix: use cloneVNode when altering props in render functions

Resolves #252

https://vuejs.org/api/render-function.html#clonevnode
This commit is contained in:
Benjamin Canac
2023-06-05 11:17:28 +02:00
parent af65683123
commit 5e50eb9eb8
3 changed files with 27 additions and 21 deletions

View File

@@ -1,4 +1,4 @@
import { h, computed, defineComponent } from 'vue' import { h, cloneVNode, computed, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { defu } from 'defu' import { defu } from 'defu'
import { classNames, getSlotsChildren } from '../../utils' 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 max = computed(() => typeof props.max === 'string' ? parseInt(props.max, 10) : props.max)
const clones = computed(() => children.value.map((node, index) => { const clones = computed(() => children.value.map((node, index) => {
const vProps: any = {}
if (!props.max || (max.value && index < max.value)) { if (!props.max || (max.value && index < max.value)) {
if (props.size) { if (props.size) {
node.props.size = props.size vProps.size = props.size
} }
node.props.class = node.props.class || '' vProps.class = node.props.class || ''
node.props.class += ` ${classNames( vProps.class += ` ${classNames(
ui.value.ring, ui.value.ring,
ui.value.margin ui.value.margin
)}` )}`
return node return cloneVNode(node, vProps)
} }
if (max.value !== undefined && index === max.value) { if (max.value !== undefined && index === max.value) {

View File

@@ -1,4 +1,4 @@
import { h, computed, defineComponent } from 'vue' import { h, cloneVNode, computed, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { defu } from 'defu' import { defu } from 'defu'
import { getSlotsChildren } from '../../utils' import { getSlotsChildren } from '../../utils'
@@ -44,28 +44,30 @@ export default defineComponent({
}[ui.value.rounded])) }[ui.value.rounded]))
const clones = computed(() => children.value.map((node, index) => { const clones = computed(() => children.value.map((node, index) => {
const vProps: any = {}
if (props.size) { if (props.size) {
node.props.size = props.size vProps.size = props.size
} }
node.props.class = node.props.class || '' vProps.class = node.props.class || ''
node.props.class += ' !shadow-none' vProps.class += ' !shadow-none'
node.props.ui = node.props.ui || {} vProps.ui = node.props.ui || {}
node.props.ui.rounded = '' vProps.ui.rounded = ''
if (index === 0) { if (index === 0) {
node.props.ui.rounded = rounded.value.left vProps.ui.rounded = rounded.value.left
} }
if (index > 0) { if (index > 0) {
node.props.class += ' -ml-px' vProps.class += ' -ml-px'
} }
if (index === children.value.length - 1) { 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) return () => h('div', { class: [ui.value.wrapper, ui.value.rounded, ui.value.shadow] }, clones.value)

View File

@@ -1,4 +1,4 @@
import { h, computed, defineComponent } from 'vue' import { h, cloneVNode, computed, defineComponent } from 'vue'
import type { PropType } from 'vue' import type { PropType } from 'vue'
import { defu } from 'defu' import { defu } from 'defu'
import { getSlotsChildren } from '../../utils' import { getSlotsChildren } from '../../utils'
@@ -53,18 +53,20 @@ export default defineComponent({
const children = computed(() => getSlotsChildren(slots)) const children = computed(() => getSlotsChildren(slots))
const clones = computed(() => children.value.map((node) => { const clones = computed(() => children.value.map((node) => {
const vProps: any = {}
if (props.error) { if (props.error) {
node.props.oldColor = node.props.color vProps.oldColor = node.props.color
node.props.color = 'red' vProps.color = 'red'
} else { } else {
node.props.color = node.props.oldColor vProps.color = vProps.oldColor
} }
if (props.name) { 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] }, [ return () => h('div', { class: [ui.value.wrapper] }, [