mirror of
https://github.com/vbenjs/gf-vben-admin.git
synced 2025-02-02 19:08:40 +08:00
fix(description): ensure that props respond
This commit is contained in:
parent
ee5fb223b6
commit
ce93e46faf
@ -148,7 +148,7 @@ Support modern browsers, not IE
|
||||
|
||||
## Maintainer
|
||||
|
||||
[@Vben](https://github.com/anncwb)。
|
||||
[@Vben](https://github.com/anncwb)
|
||||
|
||||
## Donate
|
||||
|
||||
@ -156,7 +156,7 @@ If you think this project is helpful to you, you can help the author buy a cup o
|
||||
|
||||
![donate](https://anncwb.github.io/anncwb/images/sponsor.png)
|
||||
|
||||
[Paypal Me](https://www.paypal.com/paypalme/cvvben)
|
||||
<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aed;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>
|
||||
|
||||
## Discord
|
||||
|
||||
|
@ -156,7 +156,7 @@ yarn build
|
||||
|
||||
![donate](https://anncwb.github.io/anncwb/images/sponsor.png)
|
||||
|
||||
[Paypal Me](https://www.paypal.com/paypalme/cvvben)
|
||||
<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aed;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>
|
||||
|
||||
## 交流
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
// export const Description = createAsyncComponent(() => import('./src/index'));
|
||||
|
||||
import Description from './src/index';
|
||||
import Description from './src/index.vue';
|
||||
|
||||
export { Description };
|
||||
export * from './src/types';
|
||||
|
@ -1,155 +0,0 @@
|
||||
import type { DescOptions, DescInstance, DescItem } from './types';
|
||||
|
||||
import { defineComponent, computed, ref, unref, CSSProperties } from 'vue';
|
||||
import { get } from 'lodash-es';
|
||||
import { Descriptions } from 'ant-design-vue';
|
||||
import { DescriptionsProps } from 'ant-design-vue/es/descriptions/index';
|
||||
import { CollapseContainer, CollapseContainerOptions } from '/@/components/Container/index';
|
||||
|
||||
import descProps from './props';
|
||||
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { getSlot } from '/@/utils/helper/tsxHelper';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { deepMerge } from '/@/utils';
|
||||
|
||||
const prefixCls = 'description';
|
||||
export default defineComponent({
|
||||
name: 'Description',
|
||||
props: descProps,
|
||||
emits: ['register'],
|
||||
setup(props, { attrs, slots, emit }) {
|
||||
const propsRef = ref<Partial<DescOptions> | null>(null);
|
||||
|
||||
// Custom title component: get title
|
||||
const getMergeProps = computed(() => {
|
||||
return {
|
||||
...props,
|
||||
...(unref(propsRef) as Recordable),
|
||||
} as DescOptions;
|
||||
});
|
||||
|
||||
const getProps = computed(() => {
|
||||
const opt = {
|
||||
...unref(getMergeProps),
|
||||
title: undefined,
|
||||
};
|
||||
return opt as DescOptions;
|
||||
});
|
||||
|
||||
/**
|
||||
* @description: Whether to setting title
|
||||
*/
|
||||
const useWrapper = computed(() => !!unref(getMergeProps).title);
|
||||
|
||||
/**
|
||||
* @description: Get configuration Collapse
|
||||
*/
|
||||
const getCollapseOptions = computed(
|
||||
(): CollapseContainerOptions => {
|
||||
return {
|
||||
// Cannot be expanded by default
|
||||
canExpand: false,
|
||||
...unref(getProps).collapseOptions,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
const getDescriptionsProps = computed(() => {
|
||||
return { ...attrs, ...unref(getProps) } as DescriptionsProps;
|
||||
});
|
||||
|
||||
/**
|
||||
* @description:设置desc
|
||||
*/
|
||||
function setDescProps(descProps: Partial<DescOptions>): void {
|
||||
// Keep the last setDrawerProps
|
||||
const mergeProps = deepMerge(unref(propsRef) || {}, descProps);
|
||||
propsRef.value = cloneDeep(mergeProps);
|
||||
}
|
||||
|
||||
// Prevent line breaks
|
||||
function renderLabel({ label, labelMinWidth, labelStyle }: DescItem) {
|
||||
if (!labelStyle && !labelMinWidth) {
|
||||
return label;
|
||||
}
|
||||
|
||||
const labelStyles: CSSProperties = {
|
||||
...labelStyle,
|
||||
|
||||
minWidth: `${labelMinWidth}px `,
|
||||
};
|
||||
return <div style={labelStyles}>{label}</div>;
|
||||
}
|
||||
|
||||
function renderItem() {
|
||||
const { schema, data } = unref(getProps);
|
||||
return unref(schema)
|
||||
.map((item) => {
|
||||
const { render, field, span, show, contentMinWidth } = item;
|
||||
|
||||
if (show && isFunction(show) && !show(data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const getContent = () => {
|
||||
const _data = unref(data);
|
||||
const getField = get(_data, field);
|
||||
return isFunction(render) ? render(getField, _data) : getField ?? '';
|
||||
};
|
||||
|
||||
const width = contentMinWidth;
|
||||
return (
|
||||
<Descriptions.Item label={renderLabel(item)} key={field} span={span}>
|
||||
{() => {
|
||||
if (!contentMinWidth) {
|
||||
return getContent();
|
||||
}
|
||||
const style: CSSProperties = {
|
||||
minWidth: `${width}px`,
|
||||
};
|
||||
return <div style={style}>{getContent()}</div>;
|
||||
}}
|
||||
</Descriptions.Item>
|
||||
);
|
||||
})
|
||||
.filter((item) => !!item);
|
||||
}
|
||||
|
||||
const renderDesc = () => {
|
||||
return (
|
||||
<Descriptions class={`${prefixCls}`} {...(unref(getDescriptionsProps) as any)}>
|
||||
{renderItem()}
|
||||
</Descriptions>
|
||||
);
|
||||
};
|
||||
|
||||
const renderContainer = () => {
|
||||
const content = props.useCollapse ? renderDesc() : <div>{renderDesc()}</div>;
|
||||
// Reduce the dom level
|
||||
|
||||
if (!props.useCollapse) {
|
||||
return content;
|
||||
}
|
||||
|
||||
const { canExpand, helpMessage } = unref(getCollapseOptions);
|
||||
const { title } = unref(getMergeProps);
|
||||
|
||||
return (
|
||||
<CollapseContainer title={title} canExpan={canExpand} helpMessage={helpMessage}>
|
||||
{{
|
||||
default: () => content,
|
||||
action: () => getSlot(slots, 'action'),
|
||||
}}
|
||||
</CollapseContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const methods: DescInstance = {
|
||||
setDescProps,
|
||||
};
|
||||
|
||||
emit('register', methods);
|
||||
return () => (unref(useWrapper) ? renderContainer() : renderDesc());
|
||||
},
|
||||
});
|
164
src/components/Description/src/index.vue
Normal file
164
src/components/Description/src/index.vue
Normal file
@ -0,0 +1,164 @@
|
||||
<script lang="tsx">
|
||||
import type { DescOptions, DescInstance, DescItem } from './types';
|
||||
import type { DescriptionsProps } from 'ant-design-vue/es/descriptions/index';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import type { CollapseContainerOptions } from '/@/components/Container/index';
|
||||
|
||||
import { defineComponent, computed, ref, unref } from 'vue';
|
||||
import { get } from 'lodash-es';
|
||||
import { Descriptions } from 'ant-design-vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { getSlot } from '/@/utils/helper/tsxHelper';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { deepMerge } from '/@/utils';
|
||||
|
||||
import descProps from './props';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Description',
|
||||
props: descProps,
|
||||
emits: ['register'],
|
||||
setup(props, { slots, emit }) {
|
||||
const propsRef = ref<Partial<DescOptions> | null>(null);
|
||||
|
||||
const { prefixCls } = useDesign('description');
|
||||
const attrs = useAttrs();
|
||||
|
||||
// Custom title component: get title
|
||||
const getMergeProps = computed(() => {
|
||||
return {
|
||||
...props,
|
||||
...(unref(propsRef) as Recordable),
|
||||
} as DescOptions;
|
||||
});
|
||||
|
||||
const getProps = computed(() => {
|
||||
const opt = {
|
||||
...unref(getMergeProps),
|
||||
title: undefined,
|
||||
};
|
||||
return opt as DescOptions;
|
||||
});
|
||||
|
||||
/**
|
||||
* @description: Whether to setting title
|
||||
*/
|
||||
const useWrapper = computed(() => !!unref(getMergeProps).title);
|
||||
|
||||
/**
|
||||
* @description: Get configuration Collapse
|
||||
*/
|
||||
const getCollapseOptions = computed(
|
||||
(): CollapseContainerOptions => {
|
||||
return {
|
||||
// Cannot be expanded by default
|
||||
canExpand: false,
|
||||
...unref(getProps).collapseOptions,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
const getDescriptionsProps = computed(() => {
|
||||
return { ...unref(attrs), ...unref(getProps) } as DescriptionsProps;
|
||||
});
|
||||
|
||||
/**
|
||||
* @description:设置desc
|
||||
*/
|
||||
function setDescProps(descProps: Partial<DescOptions>): void {
|
||||
// Keep the last setDrawerProps
|
||||
propsRef.value = { ...(unref(propsRef) as Recordable), ...descProps } as Recordable;
|
||||
}
|
||||
|
||||
// Prevent line breaks
|
||||
function renderLabel({ label, labelMinWidth, labelStyle }: DescItem) {
|
||||
if (!labelStyle && !labelMinWidth) {
|
||||
return label;
|
||||
}
|
||||
|
||||
const labelStyles: CSSProperties = {
|
||||
...labelStyle,
|
||||
|
||||
minWidth: `${labelMinWidth}px `,
|
||||
};
|
||||
return <div style={labelStyles}>{label}</div>;
|
||||
}
|
||||
|
||||
function renderItem() {
|
||||
const { schema, data } = unref(getProps);
|
||||
return unref(schema)
|
||||
.map((item) => {
|
||||
const { render, field, span, show, contentMinWidth } = item;
|
||||
|
||||
if (show && isFunction(show) && !show(data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const getContent = () => {
|
||||
const _data = unref(getProps)?.data;
|
||||
if (!_data) return null;
|
||||
const getField = get(_data, field);
|
||||
return isFunction(render) ? render(getField, _data) : getField ?? '';
|
||||
};
|
||||
|
||||
const width = contentMinWidth;
|
||||
return (
|
||||
<Descriptions.Item label={renderLabel(item)} key={field} span={span}>
|
||||
{() => {
|
||||
if (!contentMinWidth) {
|
||||
return getContent();
|
||||
}
|
||||
const style: CSSProperties = {
|
||||
minWidth: `${width}px`,
|
||||
};
|
||||
return <div style={style}>{getContent()}</div>;
|
||||
}}
|
||||
</Descriptions.Item>
|
||||
);
|
||||
})
|
||||
.filter((item) => !!item);
|
||||
}
|
||||
|
||||
const renderDesc = () => {
|
||||
return (
|
||||
<Descriptions class={`${prefixCls}`} {...(unref(getDescriptionsProps) as any)}>
|
||||
{renderItem()}
|
||||
</Descriptions>
|
||||
);
|
||||
};
|
||||
|
||||
const renderContainer = () => {
|
||||
const content = props.useCollapse ? renderDesc() : <div>{renderDesc()}</div>;
|
||||
// Reduce the dom level
|
||||
|
||||
if (!props.useCollapse) {
|
||||
return content;
|
||||
}
|
||||
|
||||
const { canExpand, helpMessage } = unref(getCollapseOptions);
|
||||
const { title } = unref(getMergeProps);
|
||||
|
||||
return (
|
||||
<CollapseContainer title={title} canExpan={canExpand} helpMessage={helpMessage}>
|
||||
{{
|
||||
default: () => content,
|
||||
action: () => getSlot(slots, 'action'),
|
||||
}}
|
||||
</CollapseContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const methods: DescInstance = {
|
||||
setDescProps,
|
||||
};
|
||||
|
||||
emit('register', methods);
|
||||
return () => (unref(useWrapper) ? renderContainer() : renderDesc());
|
||||
},
|
||||
});
|
||||
</script>
|
@ -1,24 +1,18 @@
|
||||
import type { PropType } from 'vue';
|
||||
import type { CollapseContainerOptions } from '/@/components/Container';
|
||||
import type { DescItem } from './types';
|
||||
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
export default {
|
||||
useCollapse: propTypes.bool.def(true),
|
||||
|
||||
title: propTypes.string.def(''),
|
||||
|
||||
size: propTypes.oneOf(['small', 'default', 'middle', undefined]).def('small'),
|
||||
|
||||
bordered: propTypes.bool.def(true),
|
||||
|
||||
column: {
|
||||
type: [Number, Object] as PropType<number | Recordable>,
|
||||
default: () => {
|
||||
return { xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 };
|
||||
},
|
||||
},
|
||||
|
||||
collapseOptions: {
|
||||
type: Object as PropType<CollapseContainerOptions>,
|
||||
default: null,
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PageFooter',
|
||||
inheritAttrs: false,
|
||||
setup() {
|
||||
const { prefixCls } = useDesign('page-footer');
|
||||
const { getCalcContentWidth } = useMenuSetting();
|
||||
|
@ -37,6 +37,7 @@
|
||||
import { PageHeader } from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
name: 'PageWrapper',
|
||||
inheritAttrs: false,
|
||||
components: { PageFooter, PageHeader },
|
||||
props: {
|
||||
dense: propTypes.bool,
|
||||
|
@ -72,12 +72,13 @@
|
||||
schema: schema,
|
||||
});
|
||||
|
||||
const [register1] = useDescription({
|
||||
const [register1, { setDescProps }] = useDescription({
|
||||
title: '无边框',
|
||||
bordered: false,
|
||||
data: mockData,
|
||||
schema: schema,
|
||||
});
|
||||
|
||||
return { mockData, schema, register, register1 };
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user