chore: 容器框架升级,修复项目命令行异常问题
This commit is contained in:
255
apps/platform/src/adapter/component/index.ts
Normal file
255
apps/platform/src/adapter/component/index.ts
Normal file
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用
|
||||
* 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
|
||||
*/
|
||||
|
||||
import type { Component } from 'vue';
|
||||
|
||||
import type { BaseFormComponentType } from '@vben/common-ui';
|
||||
import type { Recordable } from '@vben/types';
|
||||
|
||||
import { defineComponent, getCurrentInstance, h, ref } from 'vue';
|
||||
|
||||
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
import {
|
||||
ElButton,
|
||||
ElCheckbox,
|
||||
ElCheckboxButton,
|
||||
ElCheckboxGroup,
|
||||
ElDatePicker,
|
||||
ElDivider,
|
||||
ElInput,
|
||||
ElInputNumber,
|
||||
ElNotification,
|
||||
ElRadio,
|
||||
ElRadioButton,
|
||||
ElRadioGroup,
|
||||
ElSelectV2,
|
||||
ElSpace,
|
||||
ElSwitch,
|
||||
ElTimePicker,
|
||||
ElTreeSelect,
|
||||
ElUpload,
|
||||
} from 'element-plus';
|
||||
|
||||
const withDefaultPlaceholder = <T extends Component>(
|
||||
component: T,
|
||||
type: 'input' | 'select',
|
||||
) => {
|
||||
return defineComponent({
|
||||
inheritAttrs: false,
|
||||
name: component.name,
|
||||
setup: (props: any, { attrs, expose, slots }) => {
|
||||
const placeholder =
|
||||
props?.placeholder ||
|
||||
attrs?.placeholder ||
|
||||
$t(`ui.placeholder.${type}`);
|
||||
// 透传组件暴露的方法
|
||||
const innerRef = ref();
|
||||
const publicApi: Recordable<any> = {};
|
||||
expose(publicApi);
|
||||
const instance = getCurrentInstance();
|
||||
instance?.proxy?.$nextTick(() => {
|
||||
for (const key in innerRef.value) {
|
||||
if (typeof innerRef.value[key] === 'function') {
|
||||
publicApi[key] = innerRef.value[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
return () =>
|
||||
h(component, { ...props, ...attrs, placeholder, ref: innerRef }, slots);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
|
||||
export type ComponentType =
|
||||
| 'ApiSelect'
|
||||
| 'ApiTreeSelect'
|
||||
| 'Checkbox'
|
||||
| 'CheckboxGroup'
|
||||
| 'DatePicker'
|
||||
| 'Divider'
|
||||
| 'IconPicker'
|
||||
| 'Input'
|
||||
| 'InputNumber'
|
||||
| 'RadioGroup'
|
||||
| 'Select'
|
||||
| 'Space'
|
||||
| 'Switch'
|
||||
| 'TimePicker'
|
||||
| 'TreeSelect'
|
||||
| 'Upload'
|
||||
| BaseFormComponentType;
|
||||
|
||||
async function initComponentAdapter() {
|
||||
const components: Partial<Record<ComponentType, Component>> = {
|
||||
// 如果你的组件体积比较大,可以使用异步加载
|
||||
// Button: () =>
|
||||
// import('xxx').then((res) => res.Button),
|
||||
ApiSelect: (props, { attrs, slots }) => {
|
||||
return h(
|
||||
ApiComponent,
|
||||
{
|
||||
placeholder: $t('ui.placeholder.select'),
|
||||
...props,
|
||||
...attrs,
|
||||
component: ElSelectV2,
|
||||
loadingSlot: 'loading',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
},
|
||||
slots,
|
||||
);
|
||||
},
|
||||
ApiTreeSelect: (props, { attrs, slots }) => {
|
||||
return h(
|
||||
ApiComponent,
|
||||
{
|
||||
placeholder: $t('ui.placeholder.select'),
|
||||
...props,
|
||||
...attrs,
|
||||
component: ElTreeSelect,
|
||||
props: { label: 'label', children: 'children' },
|
||||
nodeKey: 'value',
|
||||
loadingSlot: 'loading',
|
||||
optionsPropName: 'data',
|
||||
visibleEvent: 'onVisibleChange',
|
||||
},
|
||||
slots,
|
||||
);
|
||||
},
|
||||
Checkbox: ElCheckbox,
|
||||
CheckboxGroup: (props, { attrs, slots }) => {
|
||||
let defaultSlot;
|
||||
if (Reflect.has(slots, 'default')) {
|
||||
defaultSlot = slots.default;
|
||||
} else {
|
||||
const { options, isButton } = attrs;
|
||||
if (Array.isArray(options)) {
|
||||
defaultSlot = () =>
|
||||
options.map((option) =>
|
||||
h(isButton ? ElCheckboxButton : ElCheckbox, option),
|
||||
);
|
||||
}
|
||||
}
|
||||
return h(
|
||||
ElCheckboxGroup,
|
||||
{ ...props, ...attrs },
|
||||
{ ...slots, default: defaultSlot },
|
||||
);
|
||||
},
|
||||
// 自定义默认按钮
|
||||
DefaultButton: (props, { attrs, slots }) => {
|
||||
return h(ElButton, { ...props, attrs, type: 'info' }, slots);
|
||||
},
|
||||
// 自定义主要按钮
|
||||
PrimaryButton: (props, { attrs, slots }) => {
|
||||
return h(ElButton, { ...props, attrs, type: 'primary' }, slots);
|
||||
},
|
||||
Divider: ElDivider,
|
||||
IconPicker: (props, { attrs, slots }) => {
|
||||
return h(
|
||||
IconPicker,
|
||||
{
|
||||
iconSlot: 'append',
|
||||
modelValueProp: 'model-value',
|
||||
inputComponent: ElInput,
|
||||
...props,
|
||||
...attrs,
|
||||
},
|
||||
slots,
|
||||
);
|
||||
},
|
||||
Input: withDefaultPlaceholder(ElInput, 'input'),
|
||||
InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
|
||||
RadioGroup: (props, { attrs, slots }) => {
|
||||
let defaultSlot;
|
||||
if (Reflect.has(slots, 'default')) {
|
||||
defaultSlot = slots.default;
|
||||
} else {
|
||||
const { options } = attrs;
|
||||
if (Array.isArray(options)) {
|
||||
defaultSlot = () =>
|
||||
options.map((option) =>
|
||||
h(attrs.isButton ? ElRadioButton : ElRadio, option),
|
||||
);
|
||||
}
|
||||
}
|
||||
return h(
|
||||
ElRadioGroup,
|
||||
{ ...props, ...attrs },
|
||||
{ ...slots, default: defaultSlot },
|
||||
);
|
||||
},
|
||||
Select: (props, { attrs, slots }) => {
|
||||
return h(ElSelectV2, { ...props, attrs }, slots);
|
||||
},
|
||||
Space: ElSpace,
|
||||
Switch: ElSwitch,
|
||||
TimePicker: (props, { attrs, slots }) => {
|
||||
const { name, id, isRange } = props;
|
||||
const extraProps: Recordable<any> = {};
|
||||
if (isRange) {
|
||||
if (name && !Array.isArray(name)) {
|
||||
extraProps.name = [name, `${name}_end`];
|
||||
}
|
||||
if (id && !Array.isArray(id)) {
|
||||
extraProps.id = [id, `${id}_end`];
|
||||
}
|
||||
}
|
||||
return h(
|
||||
ElTimePicker,
|
||||
{
|
||||
...props,
|
||||
...attrs,
|
||||
...extraProps,
|
||||
},
|
||||
slots,
|
||||
);
|
||||
},
|
||||
DatePicker: (props, { attrs, slots }) => {
|
||||
const { name, id, type } = props;
|
||||
const extraProps: Recordable<any> = {};
|
||||
if (type && type.includes('range')) {
|
||||
if (name && !Array.isArray(name)) {
|
||||
extraProps.name = [name, `${name}_end`];
|
||||
}
|
||||
if (id && !Array.isArray(id)) {
|
||||
extraProps.id = [id, `${id}_end`];
|
||||
}
|
||||
}
|
||||
return h(
|
||||
ElDatePicker,
|
||||
{
|
||||
...props,
|
||||
...attrs,
|
||||
...extraProps,
|
||||
},
|
||||
slots,
|
||||
);
|
||||
},
|
||||
TreeSelect: withDefaultPlaceholder(ElTreeSelect, 'select'),
|
||||
Upload: ElUpload,
|
||||
};
|
||||
|
||||
// 将组件注册到全局共享状态中
|
||||
globalShareState.setComponents(components);
|
||||
|
||||
// 定义全局共享状态中的消息提示
|
||||
globalShareState.defineMessage({
|
||||
// 复制成功消息提示
|
||||
copyPreferencesSuccess: (title, content) => {
|
||||
ElNotification({
|
||||
title,
|
||||
message: content,
|
||||
position: 'bottom-right',
|
||||
duration: 0,
|
||||
type: 'success',
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export { initComponentAdapter };
|
||||
39
apps/platform/src/adapter/form.ts
Normal file
39
apps/platform/src/adapter/form.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type {
|
||||
VbenFormSchema as FormSchema,
|
||||
VbenFormProps,
|
||||
} from '@vben/common-ui';
|
||||
|
||||
import type { ComponentType } from './component';
|
||||
|
||||
import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
setupVbenForm<ComponentType>({
|
||||
config: {
|
||||
modelPropNameMap: {
|
||||
Upload: 'fileList',
|
||||
CheckboxGroup: 'model-value',
|
||||
},
|
||||
},
|
||||
defineRules: {
|
||||
required: (value, _params, ctx) => {
|
||||
if (value === undefined || value === null || value.length === 0) {
|
||||
return $t('ui.formRules.required', [ctx.label]);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
selectRequired: (value, _params, ctx) => {
|
||||
if (value === undefined || value === null) {
|
||||
return $t('ui.formRules.selectRequired', [ctx.label]);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const useVbenForm = useForm<ComponentType>;
|
||||
|
||||
export { useVbenForm, z };
|
||||
|
||||
export type VbenFormSchema = FormSchema<ComponentType>;
|
||||
export type { VbenFormProps };
|
||||
68
apps/platform/src/adapter/vxe-table.ts
Normal file
68
apps/platform/src/adapter/vxe-table.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { h } from 'vue';
|
||||
|
||||
import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
|
||||
|
||||
import { ElButton, ElImage } from 'element-plus';
|
||||
|
||||
import { useVbenForm } from './form';
|
||||
|
||||
setupVbenVxeTable({
|
||||
configVxeTable: (vxeUI) => {
|
||||
vxeUI.setConfig({
|
||||
grid: {
|
||||
align: 'center',
|
||||
border: false,
|
||||
columnConfig: {
|
||||
resizable: true,
|
||||
},
|
||||
minHeight: 180,
|
||||
formConfig: {
|
||||
// 全局禁用vxe-table的表单配置,使用formOptions
|
||||
enabled: false,
|
||||
},
|
||||
proxyConfig: {
|
||||
autoLoad: true,
|
||||
response: {
|
||||
result: 'items',
|
||||
total: 'total',
|
||||
list: 'items',
|
||||
},
|
||||
showActiveMsg: true,
|
||||
showResponseMsg: false,
|
||||
},
|
||||
round: true,
|
||||
showOverflow: true,
|
||||
size: 'small',
|
||||
},
|
||||
});
|
||||
|
||||
// 表格配置项可以用 cellRender: { name: 'CellImage' },
|
||||
vxeUI.renderer.add('CellImage', {
|
||||
renderTableDefault(_renderOpts, params) {
|
||||
const { column, row } = params;
|
||||
const src = row[column.field];
|
||||
return h(ElImage, { src, previewSrcList: [src] });
|
||||
},
|
||||
});
|
||||
|
||||
// 表格配置项可以用 cellRender: { name: 'CellLink' },
|
||||
vxeUI.renderer.add('CellLink', {
|
||||
renderTableDefault(renderOpts) {
|
||||
const { props } = renderOpts;
|
||||
return h(
|
||||
ElButton,
|
||||
{ size: 'small', link: true },
|
||||
{ default: () => props?.text },
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
// 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
|
||||
// vxeUI.formats.add
|
||||
},
|
||||
useVbenForm,
|
||||
});
|
||||
|
||||
export { useVbenVxeGrid };
|
||||
|
||||
export type * from '@vben/plugins/vxe-table';
|
||||
Reference in New Issue
Block a user