index.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /**
  2. * 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用
  3. * 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
  4. */
  5. import type { Component } from 'vue';
  6. import type { BaseFormComponentType } from '@vben/common-ui';
  7. import type { Recordable } from '@vben/types';
  8. import { defineComponent, getCurrentInstance, h, ref } from 'vue';
  9. import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
  10. import { $t } from '@vben/locales';
  11. import {
  12. AutoComplete,
  13. Button,
  14. Checkbox,
  15. CheckboxGroup,
  16. DatePicker,
  17. Divider,
  18. Input,
  19. InputNumber,
  20. InputPassword,
  21. Mentions,
  22. notification,
  23. Radio,
  24. RadioGroup,
  25. RangePicker,
  26. Rate,
  27. Select,
  28. Space,
  29. Switch,
  30. Textarea,
  31. TimePicker,
  32. TreeSelect,
  33. Upload,
  34. } from 'ant-design-vue';
  35. const withDefaultPlaceholder = <T extends Component>(
  36. component: T,
  37. type: 'input' | 'select',
  38. ) => {
  39. return defineComponent({
  40. inheritAttrs: false,
  41. name: component.name,
  42. setup: (props: any, { attrs, expose, slots }) => {
  43. const placeholder =
  44. props?.placeholder ||
  45. attrs?.placeholder ||
  46. $t(`ui.placeholder.${type}`);
  47. // 透传组件暴露的方法
  48. const innerRef = ref();
  49. const publicApi: Recordable<any> = {};
  50. expose(publicApi);
  51. const instance = getCurrentInstance();
  52. instance?.proxy?.$nextTick(() => {
  53. for (const key in innerRef.value) {
  54. if (typeof innerRef.value[key] === 'function') {
  55. publicApi[key] = innerRef.value[key];
  56. }
  57. }
  58. });
  59. return () =>
  60. h(component, { ...props, ...attrs, placeholder, ref: innerRef }, slots);
  61. },
  62. });
  63. };
  64. // 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
  65. export type ComponentType =
  66. | 'ApiSelect'
  67. | 'ApiTreeSelect'
  68. | 'AutoComplete'
  69. | 'Checkbox'
  70. | 'CheckboxGroup'
  71. | 'DatePicker'
  72. | 'DefaultButton'
  73. | 'Divider'
  74. | 'IconPicker'
  75. | 'Input'
  76. | 'InputNumber'
  77. | 'InputPassword'
  78. | 'Mentions'
  79. | 'PrimaryButton'
  80. | 'Radio'
  81. | 'RadioGroup'
  82. | 'RangePicker'
  83. | 'Rate'
  84. | 'Select'
  85. | 'Space'
  86. | 'Switch'
  87. | 'Textarea'
  88. | 'TimePicker'
  89. | 'TreeSelect'
  90. | 'Upload'
  91. | BaseFormComponentType;
  92. async function initComponentAdapter() {
  93. const components: Partial<Record<ComponentType, Component>> = {
  94. // 如果你的组件体积比较大,可以使用异步加载
  95. // Button: () =>
  96. // import('xxx').then((res) => res.Button),
  97. ApiSelect: (props, { attrs, slots }) => {
  98. return h(
  99. ApiComponent,
  100. {
  101. placeholder: $t('ui.placeholder.select'),
  102. ...props,
  103. ...attrs,
  104. component: Select,
  105. loadingSlot: 'suffixIcon',
  106. visibleEvent: 'onDropdownVisibleChange',
  107. modelPropName: 'value',
  108. },
  109. slots,
  110. );
  111. },
  112. ApiTreeSelect: (props, { attrs, slots }) => {
  113. return h(
  114. ApiComponent,
  115. {
  116. placeholder: $t('ui.placeholder.select'),
  117. ...props,
  118. ...attrs,
  119. component: TreeSelect,
  120. fieldNames: { label: 'label', value: 'value', children: 'children' },
  121. loadingSlot: 'suffixIcon',
  122. modelPropName: 'value',
  123. optionsPropName: 'treeData',
  124. visibleEvent: 'onVisibleChange',
  125. },
  126. slots,
  127. );
  128. },
  129. AutoComplete,
  130. Checkbox,
  131. CheckboxGroup,
  132. DatePicker,
  133. // 自定义默认按钮
  134. DefaultButton: (props, { attrs, slots }) => {
  135. return h(Button, { ...props, attrs, type: 'default' }, slots);
  136. },
  137. Divider,
  138. IconPicker: (props, { attrs, slots }) => {
  139. return h(
  140. IconPicker,
  141. {
  142. iconSlot: 'addonAfter',
  143. inputComponent: Input,
  144. modelValueProp: 'value',
  145. ...props,
  146. ...attrs,
  147. },
  148. slots,
  149. );
  150. },
  151. Input: withDefaultPlaceholder(Input, 'input'),
  152. InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
  153. InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
  154. Mentions: withDefaultPlaceholder(Mentions, 'input'),
  155. // 自定义主要按钮
  156. PrimaryButton: (props, { attrs, slots }) => {
  157. return h(Button, { ...props, attrs, type: 'primary' }, slots);
  158. },
  159. Radio,
  160. RadioGroup,
  161. RangePicker,
  162. Rate,
  163. Select: withDefaultPlaceholder(Select, 'select'),
  164. Space,
  165. Switch,
  166. Textarea: withDefaultPlaceholder(Textarea, 'input'),
  167. TimePicker,
  168. TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'),
  169. Upload,
  170. };
  171. // 将组件注册到全局共享状态中
  172. globalShareState.setComponents(components);
  173. // 定义全局共享状态中的消息提示
  174. globalShareState.defineMessage({
  175. // 复制成功消息提示
  176. copyPreferencesSuccess: (title, content) => {
  177. notification.success({
  178. description: content,
  179. message: title,
  180. placement: 'bottomRight',
  181. });
  182. },
  183. });
  184. }
  185. export { initComponentAdapter };