mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-12-01 19:48:38 +08:00
fix: fixed error with no expected value in expandColumnTitle
slot (#7265)
* fix: fixed error report with no expected value in `expandColumnTitle` slot * fix: optimize optional chain * fix: use default render * refactor: use `customRenderSlot` replace `renderSlot` * style: code format * perf: optimize useColumns code * fix: fix path * feat: add customRenderSlot unit test
This commit is contained in:
parent
c717473568
commit
d870f3f8e0
11
components/_util/__mocks__/RenderSlot.tsx
Normal file
11
components/_util/__mocks__/RenderSlot.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import { customRenderSlot } from '../vnode';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RenderSlot',
|
||||
setup(_props, { slots }) {
|
||||
return () => {
|
||||
return customRenderSlot(slots, 'default', {}, () => ['default value']);
|
||||
};
|
||||
},
|
||||
});
|
26
components/_util/__tests__/vNode.test.js
Normal file
26
components/_util/__tests__/vNode.test.js
Normal file
@ -0,0 +1,26 @@
|
||||
import RenderSlot from '../__mocks__/RenderSlot';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import { nextTick } from 'vue';
|
||||
|
||||
describe('render slot content', () => {
|
||||
it('renders slot content', () => {
|
||||
const wrapper = mount(RenderSlot, {
|
||||
slots: {
|
||||
default: () => 'This is slot content',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.html()).toContain('This is slot content');
|
||||
});
|
||||
|
||||
it('render default value when slot is fragment', async () => {
|
||||
const wrapper = mount(RenderSlot, {
|
||||
slots: {
|
||||
default: () => <></>,
|
||||
},
|
||||
});
|
||||
|
||||
await nextTick();
|
||||
expect(wrapper.html()).toContain('default value');
|
||||
});
|
||||
});
|
@ -1,6 +1,6 @@
|
||||
import { filterEmpty } from './props-util';
|
||||
import type { VNode, VNodeProps } from 'vue';
|
||||
import { cloneVNode, isVNode, render as VueRender } from 'vue';
|
||||
import type { Slots, VNode, VNodeArrayChildren, VNodeProps } from 'vue';
|
||||
import { cloneVNode, isVNode, Comment, Fragment, render as VueRender } from 'vue';
|
||||
import warning from './warning';
|
||||
import type { RefObject } from './createRef';
|
||||
type NodeProps = Record<string, any> &
|
||||
@ -55,3 +55,28 @@ export function deepCloneElement<T, U>(
|
||||
export function triggerVNodeUpdate(vm: VNode, attrs: Record<string, any>, dom: any) {
|
||||
VueRender(cloneVNode(vm, { ...attrs }), dom);
|
||||
}
|
||||
|
||||
const ensureValidVNode = (slot: VNodeArrayChildren | null) => {
|
||||
return (slot || []).some(child => {
|
||||
if (!isVNode(child)) return true;
|
||||
if (child.type === Comment) return false;
|
||||
if (child.type === Fragment && !ensureValidVNode(child.children as VNodeArrayChildren))
|
||||
return false;
|
||||
return true;
|
||||
})
|
||||
? slot
|
||||
: null;
|
||||
};
|
||||
|
||||
export function customRenderSlot(
|
||||
slots: Slots,
|
||||
name: string,
|
||||
props: Record<string, unknown>,
|
||||
fallback?: () => VNodeArrayChildren,
|
||||
) {
|
||||
const slot = slots[name]?.(props);
|
||||
if (ensureValidVNode(slot)) {
|
||||
return slot;
|
||||
}
|
||||
return fallback?.();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { VNodeTypes, PropType, VNode, ExtractPropTypes, CSSProperties } from 'vue';
|
||||
import { isVNode, defineComponent, renderSlot } from 'vue';
|
||||
import { isVNode, defineComponent } from 'vue';
|
||||
import Tabs from '../tabs';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { flattenChildren, isEmptyElement, filterEmptyWithUndefined } from '../_util/props-util';
|
||||
@ -10,6 +10,8 @@ import devWarning from '../vc-util/devWarning';
|
||||
import useStyle from './style';
|
||||
import Skeleton from '../skeleton';
|
||||
import type { CustomSlotsType } from '../_util/type';
|
||||
import { customRenderSlot } from '../_util/vnode';
|
||||
|
||||
export interface CardTabListType {
|
||||
key: string;
|
||||
tab: any;
|
||||
@ -152,7 +154,7 @@ const Card = defineComponent({
|
||||
`tabList slots is deprecated, Please use \`customTab\` instead.`,
|
||||
);
|
||||
let tab = temp !== undefined ? temp : slots[name] ? slots[name](item) : null;
|
||||
tab = renderSlot(slots, 'customTab', item as any, () => [tab]);
|
||||
tab = customRenderSlot(slots, 'customTab', item as any, () => [tab]);
|
||||
return <TabPane tab={tab} key={item.key} disabled={item.disabled} />;
|
||||
})}
|
||||
</Tabs>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import classNames from '../../_util/classNames';
|
||||
import { filterEmpty, flattenChildren, isValidElement } from '../../_util/props-util';
|
||||
import type { CSSProperties, VNodeArrayChildren } from 'vue';
|
||||
import { Text, computed, defineComponent, isVNode, renderSlot } from 'vue';
|
||||
import { Text, computed, defineComponent, isVNode } from 'vue';
|
||||
|
||||
import type {
|
||||
DataIndex,
|
||||
@ -23,6 +23,7 @@ import { useInjectSticky } from '../context/StickyContext';
|
||||
import { warning } from '../../vc-util/warning';
|
||||
import type { MouseEventHandler } from '../../_util/EventInterface';
|
||||
import eagerComputed from '../../_util/eagerComputed';
|
||||
import { customRenderSlot } from 'ant-design-vue/es/_util/vnode';
|
||||
|
||||
/** Check if cell is in hover range */
|
||||
function inHoverRange(cellStartRow: number, cellRowSpan: number, startRow: number, endRow: number) {
|
||||
@ -223,7 +224,7 @@ export default defineComponent<CellProps>({
|
||||
contextSlots.value.bodyCell &&
|
||||
!column.slots?.customRender
|
||||
) {
|
||||
const child = renderSlot(
|
||||
const child = customRenderSlot(
|
||||
contextSlots.value,
|
||||
'bodyCell',
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { warning } from '../../vc-util/warning';
|
||||
import type { ComputedRef, Ref } from 'vue';
|
||||
import { renderSlot, computed, watchEffect } from 'vue';
|
||||
import { computed, watchEffect } from 'vue';
|
||||
import type {
|
||||
ColumnsType,
|
||||
ColumnType,
|
||||
@ -14,6 +14,7 @@ import type {
|
||||
import { INTERNAL_COL_DEFINE } from '../utils/legacyUtil';
|
||||
import { EXPAND_COLUMN } from '../constant';
|
||||
import { useInjectSlots } from '../../table/context';
|
||||
import { customRenderSlot } from '../../_util/vnode';
|
||||
|
||||
function flatColumns<RecordType>(columns: ColumnsType<RecordType>): ColumnType<RecordType>[] {
|
||||
return columns.reduce((list, column) => {
|
||||
@ -179,7 +180,7 @@ function useColumns<RecordType>(
|
||||
class: `${prefixCls.value}-expand-icon-col`,
|
||||
columnType: 'EXPAND_COLUMN',
|
||||
},
|
||||
title: renderSlot(contextSlots.value, 'expandColumnTitle', {}, () => ['']),
|
||||
title: customRenderSlot(contextSlots.value, 'expandColumnTitle', {}, () => ['']),
|
||||
fixed: fixedColumn,
|
||||
class: `${prefixCls.value}-row-expand-icon-cell`,
|
||||
width: expandColumnWidth.value,
|
||||
|
Loading…
Reference in New Issue
Block a user