@qin-ui/antd-vue-pro 2.6.0 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/api.json +2 -2
  2. package/es/antd-vue-pro.css +6 -8
  3. package/es/components/component-provider/components/index.vue.d.ts.map +1 -1
  4. package/es/components/form/components/BaseField/index.vue.d.ts.map +1 -1
  5. package/es/components/form/components/BaseField/utils/index.d.ts +1 -2
  6. package/es/components/form/components/BaseField/utils/index.d.ts.map +1 -1
  7. package/es/components/form/components/ProForm/index.vue.d.ts.map +1 -1
  8. package/es/components/table/components/ProTable.vue.d.ts +8 -2
  9. package/es/components/table/components/ProTable.vue.d.ts.map +1 -1
  10. package/es/components/table/hooks/useEllipsisTooltipColumns.d.ts.map +1 -1
  11. package/es/components/table/types/index.d.ts +1 -0
  12. package/es/components/table/types/index.d.ts.map +1 -1
  13. package/es/index.js +111 -36
  14. package/es/index.js.map +1 -1
  15. package/es/shared/core/index.d.ts +1 -1
  16. package/es/shared/core/index.d.ts.map +1 -1
  17. package/es/shared/ui/index.d.ts +1 -1
  18. package/es/shared/ui/index.d.ts.map +1 -1
  19. package/package.json +2 -2
  20. package/src/components/component-provider/components/index.vue +31 -8
  21. package/src/components/form/components/BaseField/index.vue +21 -12
  22. package/src/components/form/components/BaseField/utils/index.ts +5 -5
  23. package/src/components/form/components/ProForm/index.vue +12 -5
  24. package/src/components/table/components/ProTable.vue +72 -20
  25. package/src/components/table/hooks/useEllipsisTooltipColumns.ts +16 -1
  26. package/src/components/table/types/index.ts +1 -0
  27. package/src/shared/core/index.ts +2 -0
  28. package/src/shared/ui/index.ts +1 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * 统一 re-export @qin-ui/pro-components-core,包内所有文件通过此文件引入 core 内容。
3
3
  */
4
- export { type AdditionalMethods, localePacks, normalizeColumn, normalizeColumns, useForm, createFormProxy, useTable, useSearchFormExpand, useFields, resolveFieldIdentity, DEFAULT_FIELD_IDENTITY_KEYS, useFormData, useFormRef, useReactiveAttrs, InjectionFormKey, InjectionFormSlotsKey, getObject, omitBy, get, set, normalizePathKey, toPath, camelizeProperties, cloneDeep, pick, omit, isPlainObject, isObjectItem, isPromise, zhCN, zhTW, enUS, format, resolveLocaleName, type ProLocale, type ProLocaleName, type ProLocaleKey, type Data, type Path, type Paths, type KeyExpandString, type ExtendWithAny, type DeepPartial, type PageParam, type Fields, type Form, type Table, type UseFieldsReturn, type UseFormDataReturn, type UseFormRefReturn, } from '@qin-ui/pro-components-core';
4
+ export { type AdditionalMethods, localePacks, normalizeColumn, normalizeColumns, useForm, createFormProxy, useTable, useSearchFormExpand, useFields, resolveFieldIdentity, DEFAULT_FIELD_IDENTITY_KEYS, useFormData, useFormRef, useReactiveAttrs, InjectionFormKey, InjectionFormSlotsKey, getObject, mergeComponentVars, omitBy, get, set, normalizePathKey, toPath, camelizeProperties, cloneDeep, pick, omit, isPlainObject, isObjectItem, isPromise, callListeners, zhCN, zhTW, enUS, format, resolveLocaleName, type ProLocale, type ProLocaleName, type ProLocaleKey, type Data, type Path, type Paths, type KeyExpandString, type ExtendWithAny, type DeepPartial, type PageParam, type Fields, type Form, type Table, type UseFieldsReturn, type UseFormDataReturn, type UseFormRefReturn, } from '@qin-ui/pro-components-core';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAEL,KAAK,iBAAiB,EACtB,WAAW,EACX,eAAe,EACf,gBAAgB,EAEhB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,mBAAmB,EACnB,SAAS,EACT,oBAAoB,EACpB,2BAA2B,EAC3B,WAAW,EACX,UAAU,EACV,gBAAgB,EAEhB,gBAAgB,EAChB,qBAAqB,EAErB,SAAS,EACT,MAAM,EACN,GAAG,EACH,GAAG,EACH,gBAAgB,EAChB,MAAM,EACN,kBAAkB,EAClB,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,aAAa,EACb,YAAY,EACZ,SAAS,EAET,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,iBAAiB,EACjB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,YAAY,EAEjB,KAAK,IAAI,EACT,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAEL,KAAK,iBAAiB,EACtB,WAAW,EACX,eAAe,EACf,gBAAgB,EAEhB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,mBAAmB,EACnB,SAAS,EACT,oBAAoB,EACpB,2BAA2B,EAC3B,WAAW,EACX,UAAU,EACV,gBAAgB,EAEhB,gBAAgB,EAChB,qBAAqB,EAErB,SAAS,EACT,kBAAkB,EAClB,MAAM,EACN,GAAG,EACH,GAAG,EACH,gBAAgB,EAChB,MAAM,EACN,kBAAkB,EAClB,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,aAAa,EACb,YAAY,EACZ,SAAS,EACT,aAAa,EAEb,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,iBAAiB,EACjB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,YAAY,EAEjB,KAAK,IAAI,EACT,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,6BAA6B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { FormProps as _FormProps, Table, TableProps as _TableProps } from 'ant-design-vue';
2
2
  import { ComponentProps } from 'vue-component-type-helpers';
3
3
  import { Options } from 'scroll-into-view-if-needed';
4
- export { theme, Form, FormItem, Row as Grid, Col as GridItem, Table, Space, MenuDivider, Dropdown, Menu, MenuItem, Checkbox, Button, Cascader, CheckboxGroup, DatePicker, Input, InputNumber, InputPassword, InputSearch, RadioGroup, Select, Slider, Switch, Textarea, TimePicker, Transfer, TreeSelect, RangePicker, Tooltip, type FormItemInstance, type FormInstance, type RowProps as GridProps, type ColProps as GridItemProps, type FormItemProps, type PaginationProps, } from 'ant-design-vue';
4
+ export { theme, Form, FormItem, Row as Grid, Col as GridItem, Table, TableColumn, Space, MenuDivider, Dropdown, Menu, MenuItem, Checkbox, Button, Cascader, CheckboxGroup, DatePicker, Input, InputNumber, InputPassword, InputSearch, RadioGroup, Select, Slider, Switch, Textarea, TimePicker, Transfer, TreeSelect, RangePicker, Tooltip, type FormItemInstance, type FormInstance, type RowProps as GridProps, type ColProps as GridItemProps, type FormItemProps, type PaginationProps, } from 'ant-design-vue';
5
5
  export { type ColumnType, tableProps } from 'ant-design-vue/es/table';
6
6
  export type { TooltipProps } from 'ant-design-vue';
7
7
  export { type RangePickerProps } from 'ant-design-vue/es/date-picker';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,IAAI,UAAU,EACvB,KAAK,EACL,UAAU,IAAI,WAAW,EAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EACL,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,GAAG,IAAI,IAAI,EACX,GAAG,IAAI,QAAQ,EACf,KAAK,EACL,KAAK,EACL,WAAW,EACX,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,aAAa,EACb,UAAU,EACV,KAAK,EACL,WAAW,EACX,aAAa,EACb,WAAW,EACX,UAAU,EACV,MAAM,EACN,MAAM,EACN,MAAM,EACN,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,UAAU,EACV,WAAW,EACX,OAAO,EACP,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,QAAQ,IAAI,SAAS,EAC1B,KAAK,QAAQ,IAAI,aAAa,EAC9B,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACtE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACnF,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAEzE,oDAAoD;AACpD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,oBAAoB,CAAC,GAAG;IAC/D,kBAAkB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAC7C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,0BAA0B,CAAC,EAAE,cAAc,CACzC,OAAO,KAAK,CACb,CAAC,0BAA0B,CAAC,CAAC;CAC/B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,IAAI,UAAU,EACvB,KAAK,EACL,UAAU,IAAI,WAAW,EAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EACL,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,GAAG,IAAI,IAAI,EACX,GAAG,IAAI,QAAQ,EACf,KAAK,EACL,WAAW,EACX,KAAK,EACL,WAAW,EACX,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,aAAa,EACb,UAAU,EACV,KAAK,EACL,WAAW,EACX,aAAa,EACb,WAAW,EACX,UAAU,EACV,MAAM,EACN,MAAM,EACN,MAAM,EACN,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,UAAU,EACV,WAAW,EACX,OAAO,EACP,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,QAAQ,IAAI,SAAS,EAC1B,KAAK,QAAQ,IAAI,aAAa,EAC9B,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACtE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACnF,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAEzE,oDAAoD;AACpD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,oBAAoB,CAAC,GAAG;IAC/D,kBAAkB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAC7C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,0BAA0B,CAAC,EAAE,cAAc,CACzC,OAAO,KAAK,CACb,CAAC,0BAA0B,CAAC,CAAC;CAC/B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qin-ui/antd-vue-pro",
3
- "version": "2.6.0",
3
+ "version": "2.6.2",
4
4
  "description": "二次封装antd vue组件",
5
5
  "bin": {
6
6
  "antd-vue-pro": "./bin/init-ai.mjs"
@@ -44,7 +44,7 @@
44
44
  "dependencies": {
45
45
  "scroll-into-view-if-needed": "^3.1.0",
46
46
  "vue-component-type-helpers": "^3.2.5",
47
- "@qin-ui/pro-components-core": "^2.1.2"
47
+ "@qin-ui/pro-components-core": "^2.2.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/node": "^24",
@@ -36,8 +36,8 @@ import {
36
36
  ensureInjectConfig,
37
37
  } from '../constants';
38
38
  import type { ComponentVars } from '../types';
39
- import { computed, provide } from 'vue';
40
- import { getObject, omit } from '../../../shared/core';
39
+ import { computed, inject, provide, toValue, type InjectionKey } from 'vue';
40
+ import { getObject, mergeComponentVars, omit } from '../../../shared/core';
41
41
  import type { ComponentName } from '../../form/constants';
42
42
  import { LOCALE_INJECT_KEY, type ProLocale } from '../../../locale';
43
43
 
@@ -77,20 +77,25 @@ const props = withDefaults(defineProps<Props>(), {
77
77
  });
78
78
 
79
79
  /*
80
- * 遍历 componentVars 的每个 key,获取或创建对应的 inject 配置
81
- * 将用户提供的值合并到默认值上,剔除该注入项的不可注入键后通过 provide 响应式注入到子组件树
80
+ * 遍历 componentVars 的每个 key,读取祖先注入值与本层配置合并后向下 provide
81
+ * 合并顺序为内置默认值 → 祖先注入值 → 本层 componentVars,剔除该注入项的不可注入键
82
82
  * 子组件通过 inject(config.injectionKey) 获取合并后的计算属性配置
83
83
  */
84
84
  (Object.keys(INJECT_CONFIG) as Array<keyof typeof INJECT_CONFIG>).forEach(
85
85
  key => {
86
86
  const config = INJECT_CONFIG[key];
87
87
  const ignored = config.ignoreProps;
88
+ const parentConfig = inject(
89
+ config.injectionKey as InjectionKey<any>,
90
+ undefined
91
+ );
88
92
  provide(
89
93
  config.injectionKey,
90
94
  computed(() =>
91
95
  omit(
92
96
  {
93
97
  ...config.default,
98
+ ...(toValue(parentConfig) || {}),
94
99
  ...getObject(props.componentVars?.[key as keyof ComponentVars]),
95
100
  },
96
101
  ignored ?? []
@@ -105,10 +110,14 @@ if (props.componentVars) {
105
110
  Object.keys(props.componentVars).forEach(key => {
106
111
  if (!(key in INJECT_CONFIG)) {
107
112
  const config = ensureInjectConfig(key);
113
+ const parentConfig = inject(
114
+ config.injectionKey as InjectionKey<any>,
115
+ undefined
116
+ );
108
117
  provide(
109
118
  config.injectionKey,
110
119
  computed(() => ({
111
- ...config.default,
120
+ ...(toValue(parentConfig) || {}),
112
121
  ...getObject((props.componentVars as any)?.[key]),
113
122
  }))
114
123
  );
@@ -116,22 +125,36 @@ if (props.componentVars) {
116
125
  });
117
126
  }
118
127
 
128
+ const parentComponentVars = inject(INJECT_COMPONENT_VARS, undefined);
119
129
  // 全量 componentVars:自定义组件键在运行期新增后同样可被子组件读取
120
130
  provide(
121
131
  INJECT_COMPONENT_VARS,
122
- computed(() => (props.componentVars as Record<string, any>) ?? {})
132
+ computed(() =>
133
+ mergeComponentVars(
134
+ toValue(parentComponentVars),
135
+ props.componentVars as Record<string, any>
136
+ )
137
+ )
123
138
  );
124
139
 
140
+ const parentComponents = inject(INJECT_COMPONENTS, undefined);
125
141
  // 注入自定义组件映射,BaseField 在解析组件时会优先使用此映射
126
142
  provide(
127
143
  INJECT_COMPONENTS,
128
- computed(() => props.componentMap)
144
+ computed(() => ({
145
+ ...(toValue(parentComponents) || {}),
146
+ ...(props.componentMap ?? {}),
147
+ }))
129
148
  );
130
149
 
150
+ const parentLocale = inject(LOCALE_INJECT_KEY, undefined);
131
151
  // 注入内置文案覆盖,useLocale 在解析文案时会优先使用
132
152
  provide(
133
153
  LOCALE_INJECT_KEY,
134
- computed(() => props.locale)
154
+ computed(() => ({
155
+ ...(toValue(parentLocale) || {}),
156
+ ...(props.locale ?? {}),
157
+ }))
135
158
  );
136
159
  </script>
137
160
 
@@ -40,6 +40,7 @@ import {
40
40
  import {
41
41
  cloneDeep,
42
42
  getObject,
43
+ omitBy,
43
44
  useReactiveAttrs,
44
45
  } from '../../../../shared/core';
45
46
  import {
@@ -126,20 +127,23 @@ onBeforeUnmount(() => {
126
127
  const attrs: any = useReactiveAttrs();
127
128
 
128
129
  /**
129
- * 全局默认配置注入:key = 组件名 + picker 修饰段,inject 须在 setup 同步期调用。
130
+ * 全局默认配置注入:按组件名与 picker 修饰段分别解析注入通道,inject 须在 setup 同步期调用。
130
131
  * 组件名与 `picker` 仅取 setup 期初始值——运行期变更不会切换 Provider 的默认值预设
131
132
  * (`date-picker.month` 等子类型预设需在初始渲染前确定)。
133
+ * `date-picker` 的 picker 缺省时按 `date` 段解析子类型预设。
132
134
  */
133
135
  const pickerVal = attrs.picker;
134
- const injectConfigKey =
135
- typeof props.component === 'string'
136
- ? [props.component, pickerVal].filter(Boolean).join('.')
137
- : '';
138
- const componentInjectConfig = injectConfigKey
139
- ? getInjectConfig(injectConfigKey)
136
+ const baseConfigKey =
137
+ typeof props.component === 'string' ? props.component : '';
138
+ const pickerConfigKey =
139
+ pickerVal || (baseConfigKey === 'date-picker' ? 'date' : '');
140
+ const subtypeConfigKey =
141
+ baseConfigKey && pickerConfigKey ? `${baseConfigKey}.${pickerConfigKey}` : '';
142
+ const baseInjectConfig = baseConfigKey
143
+ ? getInjectConfig(baseConfigKey)
140
144
  : undefined;
141
- const rawInjectComponentProps = componentInjectConfig
142
- ? inject(componentInjectConfig.injectionKey, componentInjectConfig.default)
145
+ const subtypeInjectConfig = subtypeConfigKey
146
+ ? getInjectConfig(subtypeConfigKey)
143
147
  : undefined;
144
148
  // 全量 componentVars:运行期新增的自定义组件键由此兜底读取
145
149
  const componentVars = inject(INJECT_COMPONENT_VARS, undefined);
@@ -197,9 +201,12 @@ const parentDisabled = useInjectDisabled();
197
201
  * 属性分为三类:绑定属性(v-model)、组件属性(传递给组件)、插槽(动态渲染)
198
202
  */
199
203
  const groupedAttrs = computed(() => {
204
+ // 库内置默认(基础键 → 子类型键)之后再铺项目配置,项目配置始终覆盖库默认
200
205
  const currentInjectProps = {
201
- ...(toValue(rawInjectComponentProps) || {}),
202
- ...getObject(toValue(componentVars)?.[injectConfigKey]),
206
+ ...getObject(baseInjectConfig?.default),
207
+ ...getObject(subtypeInjectConfig?.default),
208
+ ...getObject(toValue(componentVars)?.[baseConfigKey]),
209
+ ...getObject(toValue(componentVars)?.[subtypeConfigKey]),
203
210
  };
204
211
  const initProps = getInitProps(
205
212
  { component: props.component, picker: attrs.picker } as Field,
@@ -207,9 +214,11 @@ const groupedAttrs = computed(() => {
207
214
  t
208
215
  );
209
216
  const effectiveModelProp = attrs.modelProp ?? initProps.modelProp ?? 'value';
217
+ // 未赋值(undefined)的键不作为显式值下发,保留注入默认值与占位符兜底
218
+ const definedAttrs = omitBy(attrs, value => value === undefined);
210
219
  const mergedProps = mergeProps(
211
220
  initProps,
212
- attrs,
221
+ definedAttrs,
213
222
  { class: attrs.componentClass, style: attrs.componentStyle },
214
223
  { disabled: attrs.disabled ?? parentDisabled.value ?? initProps.disabled },
215
224
  { modelProp: effectiveModelProp }
@@ -29,8 +29,7 @@ const getPlaceholderProps = (
29
29
  /**
30
30
  * 解析字段的 Provider 默认属性
31
31
  *
32
- * @description 仅字符串组件名取注入值(含 `date-picker` 子类型段);组件对象无注入配置,返回空对象。
33
- * `date-picker` 不拼接 `picker` 段,其子类型预设由注入 key 在 BaseField 内单独解析
32
+ * @description 仅字符串组件名取注入值;占位符兜底按基础组件名解析,组件对象无注入配置,返回空对象。
34
33
  *
35
34
  * @param field - 字段配置项
36
35
  * @param injectProps - 该组件名对应的 Provider 注入默认值
@@ -43,10 +42,11 @@ export const getInitProps = (
43
42
  t: LocaleT
44
43
  ): Record<string, any> => {
45
44
  const { component } = field as any;
46
- const picker = component === 'date-picker' ? '' : (field as any).picker;
47
45
  if (typeof component === 'string') {
48
- const k = [component, picker].filter(Boolean).join('.');
49
- return { ...injectProps, ...getPlaceholderProps(k, injectProps, t) };
46
+ return {
47
+ ...injectProps,
48
+ ...getPlaceholderProps(component, injectProps, t),
49
+ };
50
50
  }
51
51
  return {};
52
52
  };
@@ -30,14 +30,14 @@
30
30
  * @param {...FormProps} ...attrs - Ant Design Vue Form 组件的其他属性
31
31
  *
32
32
  * @slot default - 默认插槽,可用于添加额外内容
33
- * @slot [path] - 以字段 path 命名的动态插槽,可用于自定义字段渲染
33
+ * @slot [path] - 以字段 path 命名的动态插槽,优先于 component 渲染;作用域含字段值 value、回写通道 onUpdate:value、disabled、path 与合并后的控件属性,可直接 v-bind 给控件
34
34
  *
35
35
  * @example
36
36
  * ```vue
37
37
  * <template>
38
38
  * <ProForm :form="form" @submit="handleSubmit">
39
- * <template #name="{ value, disabled }">
40
- * <a-input :value="value" :disabled="disabled" />
39
+ * <template #name="scoped">
40
+ * <a-input v-bind="scoped" />
41
41
  * </template>
42
42
  * </ProForm>
43
43
  * </template>
@@ -101,7 +101,14 @@ const fields = computed(() => {
101
101
  return (Array.isArray(f) ? f : f?.value) ?? [];
102
102
  });
103
103
  const formData = computed(() => currentForm.value?.formData);
104
- const setFormRef = (el: any) => currentForm.value?.setFormRef?.(el);
104
+ /*
105
+ * ref 回调按渲染期实例路由:卸载回调(null)写回该子树所属表单,
106
+ * 运行期替换 :form 后旧实例的 formRef 同步清空
107
+ */
108
+ const formRefSetter = computed(() => {
109
+ const form = currentForm.value;
110
+ return (el: any) => form?.setFormRef?.(el);
111
+ });
105
112
 
106
113
  /*
107
114
  * formKey 子树重挂载契约:以 WeakMap 为每个 form 实例生成自增 key,绑定到原生 Form 的 :key
@@ -160,7 +167,7 @@ provide(InjectionFormSlotsKey, formSlotsRef);
160
167
  <template>
161
168
  <AForm
162
169
  :key="formKey"
163
- :ref="setFormRef"
170
+ :ref="formRefSetter"
164
171
  :model="formData"
165
172
  v-bind="formAttrs"
166
173
  class="pro-form"
@@ -51,7 +51,7 @@
51
51
  * @slot search-form - 搜索区域插槽,作用域参数 form / search / reset
52
52
  * @slot button-bar - 表格头部按钮区插槽
53
53
  * @slot toolbar - 工具栏插槽
54
- * @slot default - 透传给宿主表格的默认插槽(可用于以宿主列组件声明列)
54
+ * @slot default - 透传给宿主表格的默认插槽;未显式绑定 `columns` 且表格实例无列时用于声明列,显式传入(含空数组)时以列配置为准
55
55
  * @slot table - 表格区域插槽,作用域参数 columns / dataSource / pagination / loading / size / onChange
56
56
  */
57
57
  import type {
@@ -59,15 +59,18 @@ import type {
59
59
  TableProps,
60
60
  ColumnType,
61
61
  } from '../../../shared/ui';
62
- import { Table as ATable, tableProps } from '../../../shared/ui';
62
+ import { Table as ATable, TableColumn, tableProps } from '../../../shared/ui';
63
63
  import {
64
64
  computed,
65
65
  getCurrentInstance,
66
66
  nextTick,
67
67
  onMounted,
68
+ onUpdated,
68
69
  inject,
69
70
  ref,
71
+ shallowRef,
70
72
  toValue,
73
+ triggerRef,
71
74
  watch,
72
75
  type Slot,
73
76
  } from 'vue';
@@ -81,6 +84,7 @@ import { useLocale } from '../../../locale';
81
84
  import type { Path } from '../../../shared/core';
82
85
  import {
83
86
  camelizeProperties,
87
+ callListeners,
84
88
  getObject,
85
89
  isObjectItem,
86
90
  isPlainObject,
@@ -210,16 +214,21 @@ const _search = async () => {
210
214
  if (props.search && attrs.onSearch) {
211
215
  warnSearchConfig('duplicate');
212
216
  }
213
- if (!search) return;
214
- const searchPromise = search();
215
- if (!isPromise(searchPromise)) {
217
+ const results = callListeners(search);
218
+ if (!results.length) return;
219
+ const promises = results.filter(isPromise);
220
+ if (!promises.length) {
216
221
  warnSearchConfig('not-promise');
217
222
  return;
218
223
  }
219
224
  const seq = ++searchSequence;
220
225
  loading.value = true;
221
226
  try {
222
- await searchPromise;
227
+ const settled = await Promise.allSettled(promises);
228
+ const rejected = settled.find(item => item.status === 'rejected') as
229
+ | PromiseRejectedResult
230
+ | undefined;
231
+ if (rejected) throw rejected.reason;
223
232
  } finally {
224
233
  if (seq === searchSequence) {
225
234
  loading.value = false;
@@ -254,9 +263,17 @@ type TableSlots = Omit<ComponentSlots<typeof ATable>, 'bodyCell'> &
254
263
  column: Column<RecordType>;
255
264
  }) => void;
256
265
  }>;
257
- type Slots = Omit<TableSlots & CustomSlots, 'default'>;
266
+ type Slots = Omit<TableSlots & CustomSlots, 'default'> & {
267
+ /** 透传宿主表格的默认插槽,用于以宿主列组件声明列 */
268
+ default?: Slot;
269
+ };
258
270
 
259
271
  const slots = defineSlots<Slots>();
272
+ /* 默认插槽存在性随父级重渲染更新:运行期增删插槽后插槽列模式可感知 */
273
+ const slotsRef = shallowRef<Record<string, any>>(slots);
274
+ onUpdated(() => {
275
+ triggerRef(slotsRef);
276
+ });
260
277
  const forwardedSlotNames = () =>
261
278
  (Object.keys(slots) as Array<Extract<keyof Slots, string>>).filter(
262
279
  name => !customSlotNames.includes(name as any)
@@ -366,13 +383,32 @@ const indexColumn = computed<ColumnType>(() => ({
366
383
  customRender: ({ index }) => getIndex(index),
367
384
  }));
368
385
 
386
+ /** 插槽序号列的单元格渲染:按有效分页偏移行号 */
387
+ const slotIndexRender = ({ index }: { index: number }) => getIndex(index);
388
+
369
389
  // 列来源优先级:显式绑定 > table 实例(useTable 创建的 columns);显式列原样透传,不补齐 key
370
- const computedColumns = computed<Columns<RecordType>>(() => {
371
- const cols = (resolveOwnedProp('columns') ??
390
+ const columnSource = computed<any[]>(() => {
391
+ return (resolveOwnedProp('columns') ??
372
392
  toValue(props.table?.columns) ??
373
- []) as any;
374
- const needIndex = props.addIndexColumn ?? injectProps.value.addIndexColumn;
375
- return needIndex ? [indexColumn.value, ...cols] : cols;
393
+ []) as any[];
394
+ });
395
+
396
+ /* 无列源且存在默认插槽时由宿主消费插槽列,序号列改由插槽内的列组件提供 */
397
+ const slotColumnsMode = computed(
398
+ () =>
399
+ !hasExplicitColumns.value &&
400
+ Boolean(slotsRef.value.default) &&
401
+ columnSource.value.length === 0
402
+ );
403
+ const indexEnabled = computed(() =>
404
+ Boolean(props.addIndexColumn ?? injectProps.value.addIndexColumn)
405
+ );
406
+
407
+ const computedColumns = computed<Columns<RecordType>>(() => {
408
+ if (slotColumnsMode.value) return [];
409
+ return indexEnabled.value
410
+ ? [indexColumn.value, ...columnSource.value]
411
+ : columnSource.value;
376
412
  });
377
413
 
378
414
  const ellipsisTooltipValue = computed(
@@ -397,6 +433,11 @@ const {
397
433
  () => ellipsisTooltipGlobal.value
398
434
  );
399
435
 
436
+ /* 宿主列绑定:插槽列模式下不下发列配置,其余模式始终以列配置为准 */
437
+ const hostColumns = computed(() =>
438
+ slotColumnsMode.value ? undefined : visibleComputedColumns.value
439
+ );
440
+
400
441
  /*
401
442
  * 下发给宿主表格的属性:Provider 注入为底(其不可注入键已在注入层剔除),调用方绑定与 v-model 透传值覆盖同键。
402
443
  * size / loading 为声明模型,其 onUpdate:* 回写通道不进入 attrs,无需另行剔除
@@ -535,8 +576,11 @@ const onTableChange: TableProps['onChange'] = (...args) => {
535
576
  } else if (sorterArg) {
536
577
  nextArgs[2] = resolveSorterColumn(sorterArg);
537
578
  }
538
- (attrs.onChange ?? injectProps.value.onChange)?.(...nextArgs);
539
- _search();
579
+ try {
580
+ callListeners(attrs.onChange ?? injectProps.value.onChange, ...nextArgs);
581
+ } finally {
582
+ _search();
583
+ }
540
584
  };
541
585
 
542
586
  const searchFormVisible = computed(() => {
@@ -664,7 +708,7 @@ defineExpose({
664
708
  class="pro-table_content"
665
709
  v-bind="computedTableProps"
666
710
  :loading="loading"
667
- :columns="visibleComputedColumns"
711
+ :columns="hostColumns"
668
712
  :data-source="computedDataSource"
669
713
  :pagination="computedPagination"
670
714
  @change="onTableChange"
@@ -674,8 +718,19 @@ defineExpose({
674
718
  :key="name"
675
719
  #[name]="scoped"
676
720
  >
721
+ <template v-if="name === 'default'">
722
+ <TableColumn
723
+ v-if="slotColumnsMode && indexEnabled"
724
+ key="__INDEX__"
725
+ :title="t('table.index')"
726
+ :width="80"
727
+ data-index="__INDEX__"
728
+ :custom-render="slotIndexRender"
729
+ />
730
+ <slot name="default" v-bind="scoped || {}" />
731
+ </template>
677
732
  <slot
678
- v-if="isSlotRenderable(name, scoped)"
733
+ v-else-if="isSlotRenderable(name, scoped)"
679
734
  :name="name"
680
735
  v-bind="scoped"
681
736
  />
@@ -701,15 +756,12 @@ defineExpose({
701
756
  display: flex;
702
757
  align-items: center;
703
758
  justify-content: flex-end;
759
+ margin-bottom: 8px;
704
760
 
705
761
  &:empty {
706
762
  display: none;
707
763
  }
708
764
 
709
- & + &_content {
710
- margin-top: 16px;
711
- }
712
-
713
765
  &_button-bar {
714
766
  flex: 1;
715
767
  }
@@ -6,6 +6,8 @@ type ColumnTransformResult = {
6
6
  columns: any[];
7
7
  changed: boolean;
8
8
  hasTooltip: boolean;
9
+ // 本层是否有列因环状引用被剔除
10
+ cycleSkipped: boolean;
9
11
  };
10
12
 
11
13
  /**
@@ -58,6 +60,7 @@ export function useEllipsisTooltipColumns(
58
60
  const list: any[] = [];
59
61
  let changed = false;
60
62
  let hasTooltip = false;
63
+ let cycleSkipped = false;
61
64
 
62
65
  for (const column of columns) {
63
66
  if (!isObjectItem(column) || toValue(column.hidden)) {
@@ -72,6 +75,7 @@ export function useEllipsisTooltipColumns(
72
75
  if (Array.isArray(column.children) && column.children.length > 0) {
73
76
  if (ancestors.has(column)) {
74
77
  changed = true;
78
+ cycleSkipped = true;
75
79
  continue;
76
80
  }
77
81
  ancestors.add(column);
@@ -80,6 +84,12 @@ export function useEllipsisTooltipColumns(
80
84
  childChanged = child.changed;
81
85
  childColumns = child.columns;
82
86
  childHasTooltip = child.hasTooltip;
87
+ cycleSkipped = cycleSkipped || child.cycleSkipped;
88
+ // 子列全部被过滤后分组列整体移除;环状引用剔除时保留为叶子列
89
+ if (childColumns.length === 0 && !child.cycleSkipped) {
90
+ changed = true;
91
+ continue;
92
+ }
83
93
  }
84
94
 
85
95
  const ellipsis = column.ellipsis;
@@ -125,7 +135,12 @@ export function useEllipsisTooltipColumns(
125
135
  list.push(next);
126
136
  }
127
137
 
128
- return { columns: changed ? list : columns, changed, hasTooltip };
138
+ return {
139
+ columns: changed ? list : columns,
140
+ changed,
141
+ hasTooltip,
142
+ cycleSkipped,
143
+ };
129
144
  };
130
145
 
131
146
  const state = computed(() => transformColumns(getColumns(), globalEnabled()));
@@ -112,6 +112,7 @@ export type Column<D extends Data = Data> = Omit<
112
112
  /**
113
113
  * 列是否隐藏;支持布尔、Ref 与 ComputedRef 形式,渲染期按 `toValue` 取值。
114
114
  * 分组列的子列同样参与过滤(递归生效)。
115
+ * 只读 ref(如 `computed`)经 `setColumn` 写入时会被普通值替换,可写 ref 保持绑定。
115
116
  * @default false
116
117
  */
117
118
  hidden?: MaybeRefOrComputedRef<boolean>;
@@ -23,6 +23,7 @@ export {
23
23
  InjectionFormSlotsKey,
24
24
  // utils
25
25
  getObject,
26
+ mergeComponentVars,
26
27
  omitBy,
27
28
  get,
28
29
  set,
@@ -35,6 +36,7 @@ export {
35
36
  isPlainObject,
36
37
  isObjectItem,
37
38
  isPromise,
39
+ callListeners,
38
40
  // locale
39
41
  zhCN,
40
42
  zhTW,
@@ -13,6 +13,7 @@ export {
13
13
  Row as Grid,
14
14
  Col as GridItem,
15
15
  Table,
16
+ TableColumn,
16
17
  Space,
17
18
  MenuDivider,
18
19
  Dropdown,