Skip to content

Commit

Permalink
fix(comp:card): hoisted vnode cannot be hot updated in dev mode (#997)
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzaijiang authored Jul 8, 2022
1 parent 12af8ee commit 9576f58
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 53 deletions.
6 changes: 3 additions & 3 deletions packages/components/card/demo/Basic.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
<template>
<IxRow>
<IxCol xs="24" sm="8">
<IxCard :header="{ title: 'Card title', extra: 'setting' }" size="lg">
<IxCard :header="{ title: 'Card title', suffix: 'setting' }" size="lg">
<p>Card content</p>
<p>Card content</p>
<p>Card content</p>
</IxCard>
</IxCol>
<IxCol xs="24" sm="8">
<IxCard :header="{ title: 'Card title', extra: 'setting' }">
<IxCard :header="{ title: 'Card title', suffix: 'setting' }">
<p>Card content</p>
<p>Card content</p>
<p>Card content</p>
</IxCard>
</IxCol>
<IxCol xs="24" sm="8">
<IxCard :header="{ title: 'Small card', extra: 'setting' }" size="sm">
<IxCard :header="{ title: 'Small card', suffix: 'setting' }" size="sm">
<p>Card content</p>
<p>Card content</p>
<p>Card content</p>
Expand Down
41 changes: 21 additions & 20 deletions packages/components/card/demo/Loading.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
<template>
<IxSwitch v-model:checked="loading"></IxSwitch>
<br />
<IxRow>
<IxCol xs="24" sm="8">
<IxCard :loading="loading" :header="{ title: 'Card title', suffix: 'setting' }">
<p>Card content</p>
<p>Card content</p>
<p>Card content</p>
</IxCard>
</IxCol>
<IxCol xs="24" sm="8">
<IxCard :loading="loading" :footer="footer">
<IxHeader :avatar="{ src: '/images/avatar/2.png' }" title="Card title">
<template #description>
<p>This is the description</p>
</template>
</IxHeader>
</IxCard>
</IxCol>
</IxRow>
<IxSpace vertical block>
<IxSwitch v-model:checked="loading"></IxSwitch>
<IxRow>
<IxCol xs="24" sm="8">
<IxCard :loading="loading" :header="{ title: 'Card title', suffix: 'setting' }">
<p>Card content</p>
<p>Card content</p>
<p>Card content</p>
</IxCard>
</IxCol>
<IxCol xs="24" sm="8">
<IxCard :loading="loading" :footer="footer">
<IxHeader :avatar="{ src: '/images/avatar/2.png' }" title="Card title">
<template #description>
<p>This is the description</p>
</template>
</IxHeader>
</IxCard>
</IxCol>
</IxRow>
</IxSpace>
</template>

<script lang="ts">
Expand Down
8 changes: 4 additions & 4 deletions packages/components/card/demo/Selectable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<div>Selected: {{ selected1 }}</div>
<IxCard
v-model:selected="selected1"
:header="{ title: 'Selectable', extra: 'setting' }"
:header="{ title: 'Selectable', suffix: 'setting' }"
size="lg"
selectable
@selectedChange="logSelected"
Expand All @@ -18,7 +18,7 @@
<div>Selected: {{ selected2 }}</div>
<IxCard
v-model:selected="selected1"
:header="{ title: 'Disabled and selected', extra: 'setting' }"
:header="{ title: 'Disabled and selected', suffix: 'setting' }"
selectable
disabled
>
Expand All @@ -31,7 +31,7 @@
<div>Selected: {{ selected3 }}</div>
<IxCard
v-model:selected="selected1"
:header="{ title: 'Disable and unselected', extra: 'setting' }"
:header="{ title: 'Disable and unselected', suffix: 'setting' }"
selectable
disabled
>
Expand All @@ -49,7 +49,7 @@ const selected1 = ref(true)
const selected2 = ref(true)
const selected3 = ref(false)
const logSelected = selected => {
const logSelected = (selected: boolean) => {
console.log(`selected is ${selected}`)
}
</script>
40 changes: 14 additions & 26 deletions packages/components/card/src/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import type { CardProps } from './types'

import { ComputedRef, Slots, VNode, VNodeTypes, computed, defineComponent, isVNode, normalizeClass, provide } from 'vue'
import { Slots, VNode, VNodeTypes, computed, defineComponent, isVNode, normalizeClass, provide } from 'vue'

import { isString } from 'lodash-es'

Expand All @@ -32,12 +32,6 @@ export default defineComponent({

provide(cardToken, { hoverable })

const children = computed(() => slots.default?.() || [])
const hasGrid = computed(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return children.value.some(node => node.type && (node.type as any).name === 'IxCardGrid')
})

const [selected, setSelected] = useControlledProp(props, 'selected', false)
const isDisabled = computed(() => props.disabled)
const isSelectable = computed(() => props.selectable)
Expand All @@ -51,29 +45,28 @@ export default defineComponent({
callEmit(props.onSelectedChange, newSelected)
}

const classes = computed(() => {
return () => {
const prefixCls = mergedPrefixCls.value
const { borderless = config.borderless, loading, size = config.size, shadow } = props

const hasGridValue = hasGrid.value
const prefixCls = mergedPrefixCls.value
return normalizeClass({
const children = slots.default?.() ?? []
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const hasGrid = children.some(node => node.type && (node.type as any).name === 'IxCardGrid')

const classes = normalizeClass({
[prefixCls]: true,
[`${prefixCls}-borderless`]: borderless,
[`${prefixCls}-hoverable`]: !hasGridValue && hoverable.value,
[`${prefixCls}-hoverable`]: !hasGrid && hoverable.value,
[`${prefixCls}-loading`]: loading,
[`${prefixCls}-has-shadow`]: shadow,
[`${prefixCls}-has-grid`]: hasGridValue,
[`${prefixCls}-has-grid`]: hasGrid,
[`${prefixCls}-${size}`]: true,
[`${prefixCls}-selectable`]: isSelectable.value,
[`${prefixCls}-selected`]: isSelectable.value && selected.value,
[`${prefixCls}-disabled`]: isDisabled.value,
})
})

return () => {
const prefixCls = mergedPrefixCls.value
return (
<div class={classes.value} onClick={handleClick}>
<div class={classes} onClick={handleClick}>
{renderCover(props, slots, prefixCls)}
<ɵHeader v-slots={slots} size="sm" header={props.header} />
{renderBody(props, children, hasGrid, prefixCls)}
Expand Down Expand Up @@ -111,17 +104,12 @@ const renderCover = (props: CardProps, slots: Slots, prefixCls: string) => {
return coverNode ? <div class={`${prefixCls}-cover`}>{coverNode}</div> : undefined
}

const renderBody = (
props: CardProps,
children: ComputedRef<VNode[]>,
hasGrid: ComputedRef<boolean>,
prefixCls: string,
) => {
const renderBody = (props: CardProps, children: VNode[], hasGrid: boolean, prefixCls: string) => {
let bodyNode: VNodeTypes | undefined
if (props.loading) {
bodyNode = renderLoading(prefixCls)
} else if (children.value.length) {
bodyNode = hasGrid.value ? <IxRow>{children.value}</IxRow> : children.value
} else if (children.length) {
bodyNode = hasGrid ? <IxRow>{children}</IxRow> : children
}
return bodyNode ? <div class={`${prefixCls}-body`}>{bodyNode}</div> : undefined
}
Expand Down

0 comments on commit 9576f58

Please sign in to comment.