diff --git a/packages/components/descriptions/src/description-item.ts b/packages/components/descriptions/src/description-item.ts
index fa15cc6ccd..b32c7be10f 100644
--- a/packages/components/descriptions/src/description-item.ts
+++ b/packages/components/descriptions/src/description-item.ts
@@ -1,9 +1,21 @@
-import { defineComponent } from 'vue'
+import {
+ defineComponent,
+ getCurrentInstance,
+ inject,
+ onBeforeMount,
+ onBeforeUnmount,
+} from 'vue'
import { columnAlignment } from '@element-plus/constants'
-import { buildProps } from '@element-plus/utils'
+import { buildProps, throwError } from '@element-plus/utils'
import { COMPONENT_NAME } from './constants'
+import { descriptionsKey } from './token'
-import type { ExtractPropTypes, Slot, VNode } from 'vue'
+import type {
+ ComponentInternalInstance,
+ ExtractPropTypes,
+ Slot,
+ VNode,
+} from 'vue'
export const descriptionItemProps = buildProps({
/**
@@ -82,6 +94,30 @@ export const descriptionItemProps = buildProps({
const DescriptionItem = defineComponent({
name: COMPONENT_NAME,
props: descriptionItemProps,
+ setup(props) {
+ const descriptions = inject(descriptionsKey)
+ if (!descriptions)
+ throwError(
+ COMPONENT_NAME,
+ 'usage: '
+ )
+
+ const instance = getCurrentInstance()! as DescriptionItemInternalInstance
+
+ onBeforeMount(() => {
+ descriptions.addDescriptionItem({
+ uid: instance.uid,
+ props,
+ get vnode() {
+ return instance.vnode
+ },
+ })
+ })
+ onBeforeUnmount(() => {
+ descriptions.removeDescriptionItem(instance.uid)
+ })
+ },
+ render: () => '',
})
export default DescriptionItem
@@ -91,3 +127,6 @@ export type DescriptionItemVNode = VNode & {
children: { [name: string]: Slot } | null
props: Partial | null
}
+type DescriptionItemInternalInstance = ComponentInternalInstance & {
+ vnode: DescriptionItemVNode
+}
diff --git a/packages/components/descriptions/src/description.vue b/packages/components/descriptions/src/description.vue
index 4911034f58..f7d466a16a 100644
--- a/packages/components/descriptions/src/description.vue
+++ b/packages/components/descriptions/src/description.vue
@@ -15,9 +15,20 @@
@@ -25,17 +36,17 @@
diff --git a/packages/components/descriptions/src/descriptions-cell.ts b/packages/components/descriptions/src/descriptions-cell.ts
index 12e5d2243a..4cfb04db5e 100644
--- a/packages/components/descriptions/src/descriptions-cell.ts
+++ b/packages/components/descriptions/src/descriptions-cell.ts
@@ -5,10 +5,7 @@ import { useNamespace } from '@element-plus/hooks'
import { descriptionsKey } from './token'
import type { DirectiveArguments, PropType, VNode } from 'vue'
-import type {
- IDescriptionsInject,
- IDescriptionsItemInject,
-} from './descriptions.type'
+import type { IDescriptionsItemInject } from './type'
import type { DescriptionItemVNode } from './description-item'
export default defineComponent({
@@ -26,7 +23,7 @@ export default defineComponent({
},
},
setup() {
- const descriptions = inject(descriptionsKey, {} as IDescriptionsInject)
+ const descriptions = inject(descriptionsKey)!
return {
descriptions,
@@ -42,7 +39,7 @@ export default defineComponent({
return [dir, value, arg, modifiers]
}) as DirectiveArguments
- const { border, direction } = this.descriptions
+ const { border, direction } = this.descriptions.props
const isVertical = direction === 'vertical'
const renderLabel = () => this.cell?.children?.label?.() || item.label
const renderContent = () => this.cell?.children?.default?.()
@@ -54,7 +51,7 @@ export default defineComponent({
const labelClassName = item.labelClassName
const width =
this.type === 'label'
- ? item.labelWidth || this.descriptions.labelWidth || item.width
+ ? item.labelWidth || this.descriptions.props.labelWidth || item.width
: item.width
const style = {
@@ -109,7 +106,9 @@ export default defineComponent({
default: {
const label = renderLabel()
const labelStyle: Record = {}
- const width = addUnit(item.labelWidth || this.descriptions.labelWidth)
+ const width = addUnit(
+ item.labelWidth || this.descriptions.props.labelWidth
+ )
if (width) {
labelStyle.width = width
labelStyle.display = 'inline-block'
diff --git a/packages/components/descriptions/src/descriptions-row.vue b/packages/components/descriptions/src/descriptions-row.vue
index 7c772d5128..712bb73a48 100644
--- a/packages/components/descriptions/src/descriptions-row.vue
+++ b/packages/components/descriptions/src/descriptions-row.vue
@@ -1,5 +1,5 @@
-
+
@@ -13,7 +13,7 @@
-
+
@@ -29,13 +29,11 @@ import ElDescriptionsCell from './descriptions-cell'
import { descriptionsKey } from './token'
import { descriptionsRowProps } from './descriptions-row'
-import type { IDescriptionsInject } from './descriptions.type'
-
defineOptions({
name: 'ElDescriptionsRow',
})
defineProps(descriptionsRowProps)
-const descriptions = inject(descriptionsKey, {} as IDescriptionsInject)
+const descriptions = inject(descriptionsKey)!
diff --git a/packages/components/descriptions/src/descriptions.type.ts b/packages/components/descriptions/src/descriptions.type.ts
deleted file mode 100644
index 1b21b74bd9..0000000000
--- a/packages/components/descriptions/src/descriptions.type.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type { ColumnAlignment, ComponentSize } from '@element-plus/constants'
-
-export interface IDescriptionsInject {
- border: boolean
- column: number
- direction: 'horizontal' | 'vertical'
- size: ComponentSize
- title: string
- extra: string
- labelWidth: string | number
-}
-
-export interface IDescriptionsItemInject {
- label: string
- span: number
- rowspan: number
- width: string | number
- minWidth: string | number
- labelWidth: string | number
- align: ColumnAlignment
- labelAlign?: ColumnAlignment
- className: string
- labelClassName: string
-}
diff --git a/packages/components/descriptions/src/token.ts b/packages/components/descriptions/src/token.ts
index 5ef1fa2f10..79066419d7 100644
--- a/packages/components/descriptions/src/token.ts
+++ b/packages/components/descriptions/src/token.ts
@@ -1,5 +1,5 @@
import type { InjectionKey } from 'vue'
-import type { IDescriptionsInject } from './descriptions.type'
+import type { IDescriptionsInject } from './type'
export const descriptionsKey: InjectionKey =
Symbol('elDescriptions')
diff --git a/packages/components/descriptions/src/type.ts b/packages/components/descriptions/src/type.ts
new file mode 100644
index 0000000000..a917ca4071
--- /dev/null
+++ b/packages/components/descriptions/src/type.ts
@@ -0,0 +1,36 @@
+import type { ColumnAlignment, ComponentSize } from '@element-plus/constants'
+import type {
+ DescriptionItemProps,
+ DescriptionItemVNode,
+} from './description-item'
+
+export interface IDescriptionsInject {
+ props: {
+ border: boolean
+ column: number
+ direction: 'horizontal' | 'vertical'
+ size: ComponentSize
+ title: string
+ extra: string
+ labelWidth: string | number
+ }
+ addDescriptionItem: (item: DescriptionItemContext) => void
+ removeDescriptionItem: (uid: number) => void
+}
+export interface IDescriptionsItemInject {
+ label: string
+ span: number
+ rowspan: number
+ width: string | number
+ minWidth: string | number
+ labelWidth: string | number
+ align: ColumnAlignment
+ labelAlign?: ColumnAlignment
+ className: string
+ labelClassName: string
+}
+export interface DescriptionItemContext {
+ uid: number
+ props: DescriptionItemProps
+ vnode: DescriptionItemVNode
+}
diff --git a/packages/utils/vue/vnode.ts b/packages/utils/vue/vnode.ts
index 436d17762e..d4d7921a1a 100644
--- a/packages/utils/vue/vnode.ts
+++ b/packages/utils/vue/vnode.ts
@@ -160,9 +160,6 @@ export const flattedChildren = (
result.push(child, ...flattedChildren(child.component.subTree))
} else if (isVNode(child) && isArray(child.children)) {
result.push(...flattedChildren(child.children))
- } else if (isVNode(child) && child.shapeFlag === 2) {
- // @ts-ignore
- result.push(...flattedChildren(child.type()))
} else {
result.push(child)
}