Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: element-plus版本VbenForm Select下拉框设置Option提示“无数据” #4619

Closed
5 tasks done
arthuridea opened this issue Oct 12, 2024 · 5 comments
Closed
5 tasks done

Comments

@arthuridea
Copy link

Version

Vben Admin V5

Describe the bug?

尝试过antd版本能够正常显示选项,playground(antd)中也表现正常。
在element-plus版本中,通过schema配置后不生效。
有没有相关文档或者示例说明一下element-plus组件使用?
image

Reproduction

复制的playground下的例子,将antd相关import改成element-plus的

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (16) x64 11th Gen Intel(R) Core(TM) i7-11850H @ 2.50GHz
    Memory: 11.80 GB / 31.73 GB
  Binaries:
    Node: 20.15.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.7.0 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.12.1 - C:\Program Files\nodejs\pnpm.CMD
  Browsers:
    Edge: Chromium (129.0.2792.65)
    Internet Explorer: 11.0.26100.1882

Relevant log output

No response

Validations

@Whbbit1999
Copy link

element plus不支持在el-select上直接写options,可以自己实现一个select render,可以参考下面的代码把adapter/form.ts文件改一下就可以了

import type {
  BaseFormComponentType,
  VbenFormSchema as FormSchema,
  VbenFormProps,
} from '@vben/common-ui';

import type { Component, SetupContext } from 'vue';
import { h } from 'vue';

import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';

import {
  ElButton,
  ElCheckbox,
  ElCheckboxGroup,
  ElDivider,
  ElInput,
  ElInputNumber,
  ElOption,
  ElRadioGroup,
  ElSelect,
  ElSpace,
  ElSwitch,
  ElTimePicker,
  ElTreeSelect,
  ElUpload,
} from 'element-plus';
// 业务表单组件适配

export type FormComponentType =
  | 'Checkbox'
  | 'CheckboxGroup'
  | 'DatePicker'
  | 'Divider'
  | 'Input'
  | 'InputNumber'
  | 'RadioGroup'
  | 'Select'
  | 'Space'
  | 'Switch'
  | 'TimePicker'
  | 'TreeSelect'
  | 'Upload'
  | BaseFormComponentType;

const withDefaultPlaceholder = <T extends Component>(
  component: T,
  type: 'input' | 'select',
) => {
  return (props: any, { attrs, slots }: Omit<SetupContext, 'expose'>) => {
    const placeholder = props?.placeholder || $t(`placeholder.${type}`);
    return h(component, { ...props, ...attrs, placeholder }, slots);
  };
};

const customSelectRender = <T extends Component>(component: T) => {
  return (props: any, { attrs }: Omit<SetupContext, 'expose'>) => {
    const placeholder = props?.placeholder || $t(`placeholder.select`);
    const options = props.options;
    return h(component, { ...props, ...attrs, placeholder }, () => {
      // ElOption,
      return options?.map((option: any) =>
        h(ElOption, { label: option.label, value: option.value }),
      );
    });
  };
};

// 初始化表单组件,并注册到form组件内部
setupVbenForm<FormComponentType>({
  components: {
    Checkbox: ElCheckbox,
    CheckboxGroup: ElCheckboxGroup,
    // 自定义默认的重置按钮
    DefaultResetActionButton: (props, { attrs, slots }) => {
      return h(ElButton, { ...props, attrs, type: 'info' }, slots);
    },
    // 自定义默认的提交按钮
    DefaultSubmitActionButton: (props, { attrs, slots }) => {
      return h(ElButton, { ...props, attrs, type: 'primary' }, slots);
    },
    Divider: ElDivider,
    Input: withDefaultPlaceholder(ElInput, 'input'),
    InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
    RadioGroup: ElRadioGroup,
    Select: customSelectRender(ElSelect),
    Space: ElSpace,
    Switch: ElSwitch,
    TimePicker: ElTimePicker,
    TreeSelect: withDefaultPlaceholder(ElTreeSelect, 'select'),
    Upload: ElUpload,
  },
  config: {
    modelPropNameMap: {
      Upload: 'fileList',
    },
  },
  defineRules: {
    required: (value, _params, ctx) => {
      if (value === undefined || value === null || value.length === 0) {
        return $t('formRules.required', [ctx.label]);
      }
      return true;
    },
    selectRequired: (value, _params, ctx) => {
      if (value === undefined || value === null) {
        return $t('formRules.selectRequired', [ctx.label]);
      }
      return true;
    },
  },
});

const useVbenForm = useForm<FormComponentType>;

export { useVbenForm, z };

export type VbenFormSchema = FormSchema<FormComponentType>;
export type { VbenFormProps };

@arthuridea
Copy link
Author

element plus不支持在el-select上直接写options,可以自己实现一个select render,可以参考下面的代码把adapter/form.ts文件改一下就可以了

import type {
  BaseFormComponentType,
  VbenFormSchema as FormSchema,
  VbenFormProps,
} from '@vben/common-ui';

import type { Component, SetupContext } from 'vue';
import { h } from 'vue';

import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';

import {
  ElButton,
  ElCheckbox,
  ElCheckboxGroup,
  ElDivider,
  ElInput,
  ElInputNumber,
  ElOption,
  ElRadioGroup,
  ElSelect,
  ElSpace,
  ElSwitch,
  ElTimePicker,
  ElTreeSelect,
  ElUpload,
} from 'element-plus';
// 业务表单组件适配

export type FormComponentType =
  | 'Checkbox'
  | 'CheckboxGroup'
  | 'DatePicker'
  | 'Divider'
  | 'Input'
  | 'InputNumber'
  | 'RadioGroup'
  | 'Select'
  | 'Space'
  | 'Switch'
  | 'TimePicker'
  | 'TreeSelect'
  | 'Upload'
  | BaseFormComponentType;

const withDefaultPlaceholder = <T extends Component>(
  component: T,
  type: 'input' | 'select',
) => {
  return (props: any, { attrs, slots }: Omit<SetupContext, 'expose'>) => {
    const placeholder = props?.placeholder || $t(`placeholder.${type}`);
    return h(component, { ...props, ...attrs, placeholder }, slots);
  };
};

const customSelectRender = <T extends Component>(component: T) => {
  return (props: any, { attrs }: Omit<SetupContext, 'expose'>) => {
    const placeholder = props?.placeholder || $t(`placeholder.select`);
    const options = props.options;
    return h(component, { ...props, ...attrs, placeholder }, () => {
      // ElOption,
      return options?.map((option: any) =>
        h(ElOption, { label: option.label, value: option.value }),
      );
    });
  };
};

// 初始化表单组件,并注册到form组件内部
setupVbenForm<FormComponentType>({
  components: {
    Checkbox: ElCheckbox,
    CheckboxGroup: ElCheckboxGroup,
    // 自定义默认的重置按钮
    DefaultResetActionButton: (props, { attrs, slots }) => {
      return h(ElButton, { ...props, attrs, type: 'info' }, slots);
    },
    // 自定义默认的提交按钮
    DefaultSubmitActionButton: (props, { attrs, slots }) => {
      return h(ElButton, { ...props, attrs, type: 'primary' }, slots);
    },
    Divider: ElDivider,
    Input: withDefaultPlaceholder(ElInput, 'input'),
    InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
    RadioGroup: ElRadioGroup,
    Select: customSelectRender(ElSelect),
    Space: ElSpace,
    Switch: ElSwitch,
    TimePicker: ElTimePicker,
    TreeSelect: withDefaultPlaceholder(ElTreeSelect, 'select'),
    Upload: ElUpload,
  },
  config: {
    modelPropNameMap: {
      Upload: 'fileList',
    },
  },
  defineRules: {
    required: (value, _params, ctx) => {
      if (value === undefined || value === null || value.length === 0) {
        return $t('formRules.required', [ctx.label]);
      }
      return true;
    },
    selectRequired: (value, _params, ctx) => {
      if (value === undefined || value === null) {
        return $t('formRules.selectRequired', [ctx.label]);
      }
      return true;
    },
  },
});

const useVbenForm = useForm<FormComponentType>;

export { useVbenForm, z };

export type VbenFormSchema = FormSchema<FormComponentType>;
export type { VbenFormProps };

感谢!试了可以了。

@Whbbit1999
Copy link

element plus不支持在el-select上直接写options,可以自己实现一个select render,可以参考下面的代码把adapter/form.ts文件改一下就可以了

import type {
  BaseFormComponentType,
  VbenFormSchema as FormSchema,
  VbenFormProps,
} from '@vben/common-ui';

import type { Component, SetupContext } from 'vue';
import { h } from 'vue';

import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';

import {
  ElButton,
  ElCheckbox,
  ElCheckboxGroup,
  ElDivider,
  ElInput,
  ElInputNumber,
  ElOption,
  ElRadioGroup,
  ElSelect,
  ElSpace,
  ElSwitch,
  ElTimePicker,
  ElTreeSelect,
  ElUpload,
} from 'element-plus';
// 业务表单组件适配

export type FormComponentType =
  | 'Checkbox'
  | 'CheckboxGroup'
  | 'DatePicker'
  | 'Divider'
  | 'Input'
  | 'InputNumber'
  | 'RadioGroup'
  | 'Select'
  | 'Space'
  | 'Switch'
  | 'TimePicker'
  | 'TreeSelect'
  | 'Upload'
  | BaseFormComponentType;

const withDefaultPlaceholder = <T extends Component>(
  component: T,
  type: 'input' | 'select',
) => {
  return (props: any, { attrs, slots }: Omit<SetupContext, 'expose'>) => {
    const placeholder = props?.placeholder || $t(`placeholder.${type}`);
    return h(component, { ...props, ...attrs, placeholder }, slots);
  };
};

const customSelectRender = <T extends Component>(component: T) => {
  return (props: any, { attrs }: Omit<SetupContext, 'expose'>) => {
    const placeholder = props?.placeholder || $t(`placeholder.select`);
    const options = props.options;
    return h(component, { ...props, ...attrs, placeholder }, () => {
      // ElOption,
      return options?.map((option: any) =>
        h(ElOption, { label: option.label, value: option.value }),
      );
    });
  };
};

// 初始化表单组件,并注册到form组件内部
setupVbenForm<FormComponentType>({
  components: {
    Checkbox: ElCheckbox,
    CheckboxGroup: ElCheckboxGroup,
    // 自定义默认的重置按钮
    DefaultResetActionButton: (props, { attrs, slots }) => {
      return h(ElButton, { ...props, attrs, type: 'info' }, slots);
    },
    // 自定义默认的提交按钮
    DefaultSubmitActionButton: (props, { attrs, slots }) => {
      return h(ElButton, { ...props, attrs, type: 'primary' }, slots);
    },
    Divider: ElDivider,
    Input: withDefaultPlaceholder(ElInput, 'input'),
    InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
    RadioGroup: ElRadioGroup,
    Select: customSelectRender(ElSelect),
    Space: ElSpace,
    Switch: ElSwitch,
    TimePicker: ElTimePicker,
    TreeSelect: withDefaultPlaceholder(ElTreeSelect, 'select'),
    Upload: ElUpload,
  },
  config: {
    modelPropNameMap: {
      Upload: 'fileList',
    },
  },
  defineRules: {
    required: (value, _params, ctx) => {
      if (value === undefined || value === null || value.length === 0) {
        return $t('formRules.required', [ctx.label]);
      }
      return true;
    },
    selectRequired: (value, _params, ctx) => {
      if (value === undefined || value === null) {
        return $t('formRules.selectRequired', [ctx.label]);
      }
      return true;
    },
  },
});

const useVbenForm = useForm<FormComponentType>;

export { useVbenForm, z };

export type VbenFormSchema = FormSchema<FormComponentType>;
export type { VbenFormProps };

感谢!试了可以了。

😄这个有些缺陷,根据下面这样改一下可以把disabled props也接收到
image

@arthuridea
Copy link
Author

element plus不支持在el-select上直接写options,可以自己实现一个select render,可以参考下面的代码把adapter/form.ts文件改一下就可以了

import type {
  BaseFormComponentType,
  VbenFormSchema as FormSchema,
  VbenFormProps,
} from '@vben/common-ui';

import type { Component, SetupContext } from 'vue';
import { h } from 'vue';

import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';

import {
  ElButton,
  ElCheckbox,
  ElCheckboxGroup,
  ElDivider,
  ElInput,
  ElInputNumber,
  ElOption,
  ElRadioGroup,
  ElSelect,
  ElSpace,
  ElSwitch,
  ElTimePicker,
  ElTreeSelect,
  ElUpload,
} from 'element-plus';
// 业务表单组件适配

export type FormComponentType =
  | 'Checkbox'
  | 'CheckboxGroup'
  | 'DatePicker'
  | 'Divider'
  | 'Input'
  | 'InputNumber'
  | 'RadioGroup'
  | 'Select'
  | 'Space'
  | 'Switch'
  | 'TimePicker'
  | 'TreeSelect'
  | 'Upload'
  | BaseFormComponentType;

const withDefaultPlaceholder = <T extends Component>(
  component: T,
  type: 'input' | 'select',
) => {
  return (props: any, { attrs, slots }: Omit<SetupContext, 'expose'>) => {
    const placeholder = props?.placeholder || $t(`placeholder.${type}`);
    return h(component, { ...props, ...attrs, placeholder }, slots);
  };
};

const customSelectRender = <T extends Component>(component: T) => {
  return (props: any, { attrs }: Omit<SetupContext, 'expose'>) => {
    const placeholder = props?.placeholder || $t(`placeholder.select`);
    const options = props.options;
    return h(component, { ...props, ...attrs, placeholder }, () => {
      // ElOption,
      return options?.map((option: any) =>
        h(ElOption, { label: option.label, value: option.value }),
      );
    });
  };
};

// 初始化表单组件,并注册到form组件内部
setupVbenForm<FormComponentType>({
  components: {
    Checkbox: ElCheckbox,
    CheckboxGroup: ElCheckboxGroup,
    // 自定义默认的重置按钮
    DefaultResetActionButton: (props, { attrs, slots }) => {
      return h(ElButton, { ...props, attrs, type: 'info' }, slots);
    },
    // 自定义默认的提交按钮
    DefaultSubmitActionButton: (props, { attrs, slots }) => {
      return h(ElButton, { ...props, attrs, type: 'primary' }, slots);
    },
    Divider: ElDivider,
    Input: withDefaultPlaceholder(ElInput, 'input'),
    InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
    RadioGroup: ElRadioGroup,
    Select: customSelectRender(ElSelect),
    Space: ElSpace,
    Switch: ElSwitch,
    TimePicker: ElTimePicker,
    TreeSelect: withDefaultPlaceholder(ElTreeSelect, 'select'),
    Upload: ElUpload,
  },
  config: {
    modelPropNameMap: {
      Upload: 'fileList',
    },
  },
  defineRules: {
    required: (value, _params, ctx) => {
      if (value === undefined || value === null || value.length === 0) {
        return $t('formRules.required', [ctx.label]);
      }
      return true;
    },
    selectRequired: (value, _params, ctx) => {
      if (value === undefined || value === null) {
        return $t('formRules.selectRequired', [ctx.label]);
      }
      return true;
    },
  },
});

const useVbenForm = useForm<FormComponentType>;

export { useVbenForm, z };

export type VbenFormSchema = FormSchema<FormComponentType>;
export type { VbenFormProps };

感谢!试了可以了。

😄这个有些缺陷,根据下面这样改一下可以把disabled props也接收到 image

我再研究一下,感谢!

@mynetfan
Copy link
Collaborator

element plus 可以直接用 selectV2 这个组件代替select,它提供类似antd的options属性来自动生成备选项。
https://element-plus.org/zh-CN/component/select-v2.html

@github-actions github-actions bot locked and limited conversation to collaborators Oct 28, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants