| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- /**
- * 通用组件共同的使用的基础组件,原先放在 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 { defineAsyncComponent, defineComponent, h, ref } from 'vue';
- import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
- import { $t } from '@vben/locales';
- import { ElNotification } from 'element-plus';
- const ElButton = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/button/index'),
- import('element-plus/es/components/button/style/css'),
- ]).then(([res]) => res.ElButton),
- );
- const ElCheckbox = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/checkbox/index'),
- import('element-plus/es/components/checkbox/style/css'),
- ]).then(([res]) => res.ElCheckbox),
- );
- const ElCheckboxButton = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/checkbox/index'),
- import('element-plus/es/components/checkbox-button/style/css'),
- ]).then(([res]) => res.ElCheckboxButton),
- );
- const ElCheckboxGroup = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/checkbox/index'),
- import('element-plus/es/components/checkbox-group/style/css'),
- ]).then(([res]) => res.ElCheckboxGroup),
- );
- const ElDatePicker = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/date-picker/index'),
- import('element-plus/es/components/date-picker/style/css'),
- ]).then(([res]) => res.ElDatePicker),
- );
- const ElDivider = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/divider/index'),
- import('element-plus/es/components/divider/style/css'),
- ]).then(([res]) => res.ElDivider),
- );
- const ElInput = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/input/index'),
- import('element-plus/es/components/input/style/css'),
- ]).then(([res]) => res.ElInput),
- );
- const ElInputNumber = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/input-number/index'),
- import('element-plus/es/components/input-number/style/css'),
- ]).then(([res]) => res.ElInputNumber),
- );
- const ElRadio = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/radio/index'),
- import('element-plus/es/components/radio/style/css'),
- ]).then(([res]) => res.ElRadio),
- );
- const ElRadioButton = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/radio/index'),
- import('element-plus/es/components/radio-button/style/css'),
- ]).then(([res]) => res.ElRadioButton),
- );
- const ElRadioGroup = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/radio/index'),
- import('element-plus/es/components/radio-group/style/css'),
- ]).then(([res]) => res.ElRadioGroup),
- );
- const ElSelectV2 = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/select-v2/index'),
- import('element-plus/es/components/select-v2/style/css'),
- ]).then(([res]) => res.ElSelectV2),
- );
- const ElSpace = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/space/index'),
- import('element-plus/es/components/space/style/css'),
- ]).then(([res]) => res.ElSpace),
- );
- const ElSwitch = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/switch/index'),
- import('element-plus/es/components/switch/style/css'),
- ]).then(([res]) => res.ElSwitch),
- );
- const ElTimePicker = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/time-picker/index'),
- import('element-plus/es/components/time-picker/style/css'),
- ]).then(([res]) => res.ElTimePicker),
- );
- const ElTreeSelect = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/tree-select/index'),
- import('element-plus/es/components/tree-select/style/css'),
- ]).then(([res]) => res.ElTreeSelect),
- );
- const ElUpload = defineAsyncComponent(() =>
- Promise.all([
- import('element-plus/es/components/upload/index'),
- import('element-plus/es/components/upload/style/css'),
- ]).then(([res]) => res.ElUpload),
- );
- const withDefaultPlaceholder = <T extends Component>(
- component: T,
- type: 'input' | 'select',
- componentProps: Recordable<any> = {},
- ) => {
- return defineComponent({
- name: component.name,
- inheritAttrs: false,
- setup: (props: any, { attrs, expose, slots }) => {
- const placeholder =
- props?.placeholder ||
- attrs?.placeholder ||
- $t(`ui.placeholder.${type}`);
- // 透传组件暴露的方法
- const innerRef = ref();
- expose(
- new Proxy(
- {},
- {
- get: (_target, key) => innerRef.value?.[key],
- has: (_target, key) => key in (innerRef.value || {}),
- },
- ),
- );
- return () =>
- h(
- component,
- { ...componentProps, placeholder, ...props, ...attrs, 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: withDefaultPlaceholder(
- {
- ...ApiComponent,
- name: 'ApiSelect',
- },
- 'select',
- {
- component: ElSelectV2,
- loadingSlot: 'loading',
- visibleEvent: 'onVisibleChange',
- },
- ),
- ApiTreeSelect: withDefaultPlaceholder(
- {
- ...ApiComponent,
- name: 'ApiTreeSelect',
- },
- 'select',
- {
- component: ElTreeSelect,
- props: { label: 'label', children: 'children' },
- nodeKey: 'value',
- loadingSlot: 'loading',
- optionsPropName: 'data',
- visibleEvent: 'onVisibleChange',
- },
- ),
- 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: withDefaultPlaceholder(IconPicker, 'select', {
- iconSlot: 'append',
- modelValueProp: 'model-value',
- inputComponent: ElInput,
- }),
- 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 };
|