@qin-ui/element-plus-pro 1.1.4 → 1.2.0
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.
- package/AI-CONTEXT.md +19 -8
- package/api.json +7 -1
- package/es/components/component-provider/components/index.vue.d.ts +6 -0
- package/es/components/component-provider/components/index.vue.d.ts.map +1 -1
- package/es/components/component-provider/constants/index.d.ts.map +1 -1
- package/es/components/form/components/BaseField/index.vue.d.ts.map +1 -1
- package/es/components/form/components/BaseField/utils/index.d.ts +3 -1
- package/es/components/form/components/BaseField/utils/index.d.ts.map +1 -1
- package/es/components/table/components/ColumnControl.vue.d.ts +2 -1
- package/es/components/table/components/ColumnControl.vue.d.ts.map +1 -1
- package/es/components/table/components/ProTable.vue.d.ts +3 -2
- package/es/components/table/components/ProTable.vue.d.ts.map +1 -1
- package/es/components/table/components/SearchForm.vue.d.ts.map +1 -1
- package/es/components/table/components/SizeControl.vue.d.ts.map +1 -1
- package/es/components/table/types/index.d.ts +22 -0
- package/es/components/table/types/index.d.ts.map +1 -1
- package/es/components/table/useTable.d.ts.map +1 -1
- package/es/element-plus-pro.css +13 -13
- package/es/index.d.ts +1 -0
- package/es/index.d.ts.map +1 -1
- package/es/index.js +285 -125
- package/es/index.js.map +1 -1
- package/es/locale/en-US.d.ts +26 -0
- package/es/locale/en-US.d.ts.map +1 -0
- package/es/locale/index.d.ts +31 -0
- package/es/locale/index.d.ts.map +1 -0
- package/es/locale/zh-CN.d.ts +26 -0
- package/es/locale/zh-CN.d.ts.map +1 -0
- package/es/locale/zh-TW.d.ts +26 -0
- package/es/locale/zh-TW.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/components/component-provider/components/index.vue +14 -1
- package/src/components/component-provider/constants/index.ts +20 -39
- package/src/components/form/components/BaseField/index.vue +10 -4
- package/src/components/form/components/BaseField/utils/index.ts +66 -3
- package/src/components/table/components/ColumnControl.vue +83 -20
- package/src/components/table/components/ProTable.vue +36 -10
- package/src/components/table/components/SearchForm.vue +6 -3
- package/src/components/table/components/SizeControl.vue +9 -5
- package/src/components/table/types/index.ts +23 -0
- package/src/components/table/useTable.ts +13 -1
- package/src/index.ts +1 -0
- package/src/locale/en-US.ts +21 -0
- package/src/locale/index.ts +68 -0
- package/src/locale/zh-CN.ts +21 -0
- package/src/locale/zh-TW.ts +21 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
readonly 'date-picker.placeholder': "Please select";
|
|
3
|
+
readonly 'date-picker.start': "Start date";
|
|
4
|
+
readonly 'date-picker.end': "End date";
|
|
5
|
+
readonly 'date-picker.startMonth': "Start month";
|
|
6
|
+
readonly 'date-picker.endMonth': "End month";
|
|
7
|
+
readonly 'date-picker.startYear': "Start year";
|
|
8
|
+
readonly 'date-picker.endYear': "End year";
|
|
9
|
+
readonly 'date-picker.startTime': "Start time";
|
|
10
|
+
readonly 'date-picker.endTime': "End time";
|
|
11
|
+
readonly 'table.query': "Search";
|
|
12
|
+
readonly 'table.reset': "Reset";
|
|
13
|
+
readonly 'table.expand': "Expand";
|
|
14
|
+
readonly 'table.collapse': "Collapse";
|
|
15
|
+
readonly 'table.selectAll': "Select All";
|
|
16
|
+
readonly 'table.index': "No.";
|
|
17
|
+
readonly 'table.sizeDefault': "Default";
|
|
18
|
+
readonly 'table.sizeMiddle': "Middle";
|
|
19
|
+
readonly 'table.sizeCompact': "Compact";
|
|
20
|
+
readonly 'table.columnFallback': "Column {index}";
|
|
21
|
+
readonly 'pagination.total': "Total {total} items";
|
|
22
|
+
readonly 'input.placeholder': "Please input";
|
|
23
|
+
readonly 'select.placeholder': "Please select";
|
|
24
|
+
};
|
|
25
|
+
export default _default;
|
|
26
|
+
//# sourceMappingURL=en-US.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en-US.d.ts","sourceRoot":"","sources":["../../src/locale/en-US.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAQA,wBAYW"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { InjectionKey, MaybeRef } from 'vue';
|
|
2
|
+
import { ProLocaleName } from '@qin-ui/pro-components-core';
|
|
3
|
+
import { default as zhCN } from './zh-CN';
|
|
4
|
+
import { default as zhTW } from './zh-TW';
|
|
5
|
+
import { default as enUS } from './en-US';
|
|
6
|
+
export { zhCN, zhTW, enUS };
|
|
7
|
+
export type ProLocale = typeof zhCN;
|
|
8
|
+
/** ProComponentProvider 通过该 key 注入局部覆盖文案 */
|
|
9
|
+
export declare const LOCALE_INJECT_KEY: InjectionKey<MaybeRef<Partial<ProLocale> | undefined>>;
|
|
10
|
+
/**
|
|
11
|
+
* 获取响应式 locale 文案
|
|
12
|
+
*
|
|
13
|
+
* @description 返回 `t` 翻译函数与当前语言名。
|
|
14
|
+
* `t` 在 computed / 模板中调用时会随宿主语言切换自动更新。
|
|
15
|
+
*
|
|
16
|
+
* @returns
|
|
17
|
+
* - `t(key, params?)` - 翻译函数,支持 `{placeholder}` 参数
|
|
18
|
+
* - `lang` - 当前解析出的语言名('zh-CN' | 'zh-TW' | 'en-US')
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const { t } = useLocale();
|
|
23
|
+
* t('table.query') // '查询' / '查詢' / 'Search'
|
|
24
|
+
* t('pagination.total', { total: 100 }) // '共 100 条'
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare const useLocale: () => {
|
|
28
|
+
t: (key: string, params?: Record<string, string | number>) => string;
|
|
29
|
+
lang: import('vue').ComputedRef<ProLocaleName>;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/locale/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,QAAQ,EACd,MAAM,KAAK,CAAC;AAEb,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,IAAI,MAAM,SAAS,CAAC;AAE3B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAE5B,MAAM,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC;AAEpC,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAC1C,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAClB,CAAC;AAEzB;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,SAAS;aASJ,MAAM,WAAW,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAG,MAAM;;CAQ1E,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
readonly 'date-picker.placeholder': "请选择";
|
|
3
|
+
readonly 'date-picker.start': "开始日期";
|
|
4
|
+
readonly 'date-picker.end': "结束日期";
|
|
5
|
+
readonly 'date-picker.startMonth': "开始月份";
|
|
6
|
+
readonly 'date-picker.endMonth': "结束月份";
|
|
7
|
+
readonly 'date-picker.startYear': "开始年份";
|
|
8
|
+
readonly 'date-picker.endYear': "结束年份";
|
|
9
|
+
readonly 'date-picker.startTime': "开始时间";
|
|
10
|
+
readonly 'date-picker.endTime': "结束时间";
|
|
11
|
+
readonly 'table.query': "\u67E5\u8BE2";
|
|
12
|
+
readonly 'table.reset': "\u91CD\u7F6E";
|
|
13
|
+
readonly 'table.expand': "\u5C55\u5F00";
|
|
14
|
+
readonly 'table.collapse': "\u6536\u8D77";
|
|
15
|
+
readonly 'table.selectAll': "\u5168\u9009";
|
|
16
|
+
readonly 'table.index': "\u5E8F\u53F7";
|
|
17
|
+
readonly 'table.sizeDefault': "\u9ED8\u8BA4";
|
|
18
|
+
readonly 'table.sizeMiddle': "\u4E2D\u7B49";
|
|
19
|
+
readonly 'table.sizeCompact': "\u7D27\u51D1";
|
|
20
|
+
readonly 'table.columnFallback': "\u5217{index}";
|
|
21
|
+
readonly 'pagination.total': "\u5171 {total} \u6761";
|
|
22
|
+
readonly 'input.placeholder': "\u8BF7\u8F93\u5165";
|
|
23
|
+
readonly 'select.placeholder': "\u8BF7\u9009\u62E9";
|
|
24
|
+
};
|
|
25
|
+
export default _default;
|
|
26
|
+
//# sourceMappingURL=zh-CN.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zh-CN.d.ts","sourceRoot":"","sources":["../../src/locale/zh-CN.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAQA,wBAYW"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
readonly 'date-picker.placeholder': "請選擇";
|
|
3
|
+
readonly 'date-picker.start': "開始日期";
|
|
4
|
+
readonly 'date-picker.end': "結束日期";
|
|
5
|
+
readonly 'date-picker.startMonth': "開始月份";
|
|
6
|
+
readonly 'date-picker.endMonth': "結束月份";
|
|
7
|
+
readonly 'date-picker.startYear': "開始年份";
|
|
8
|
+
readonly 'date-picker.endYear': "結束年份";
|
|
9
|
+
readonly 'date-picker.startTime': "開始時間";
|
|
10
|
+
readonly 'date-picker.endTime': "結束時間";
|
|
11
|
+
readonly 'table.query': "\u67E5\u8A62";
|
|
12
|
+
readonly 'table.reset': "\u91CD\u8A2D";
|
|
13
|
+
readonly 'table.expand': "\u5C55\u958B";
|
|
14
|
+
readonly 'table.collapse': "\u6536\u8D77";
|
|
15
|
+
readonly 'table.selectAll': "\u5168\u9078";
|
|
16
|
+
readonly 'table.index': "\u5E8F\u865F";
|
|
17
|
+
readonly 'table.sizeDefault': "\u9810\u8A2D";
|
|
18
|
+
readonly 'table.sizeMiddle': "\u4E2D\u7B49";
|
|
19
|
+
readonly 'table.sizeCompact': "\u7DCA\u6E4A";
|
|
20
|
+
readonly 'table.columnFallback': "\u6B04{index}";
|
|
21
|
+
readonly 'pagination.total': "\u5171 {total} \u7B46";
|
|
22
|
+
readonly 'input.placeholder': "\u8ACB\u8F38\u5165";
|
|
23
|
+
readonly 'select.placeholder': "\u8ACB\u9078\u64C7";
|
|
24
|
+
};
|
|
25
|
+
export default _default;
|
|
26
|
+
//# sourceMappingURL=zh-TW.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zh-TW.d.ts","sourceRoot":"","sources":["../../src/locale/zh-TW.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAQA,wBAYW"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qin-ui/element-plus-pro",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "基于 element-plus 的二次封装组件",
|
|
5
5
|
"bin": {
|
|
6
6
|
"element-plus-pro": "./bin/init-ai.mjs"
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"vue-component-type-helpers": "^3.2.5",
|
|
42
|
-
"@qin-ui/pro-components-core": "^1.0
|
|
42
|
+
"@qin-ui/pro-components-core": "^1.1.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"element-plus": "^2.13.6"
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @param {ComponentVars} [componentVars] - 组件全局配置变量
|
|
9
9
|
* @param {Record<ComponentName, any>} [componentMap] - 自定义组件映射
|
|
10
|
+
* @param {Partial<ProLocale>} [locale] - 内置文案覆盖,可覆盖任意 locale 文案(如查询/重置/序号/占位符等)
|
|
10
11
|
*
|
|
11
12
|
* @slot default - 子组件内容
|
|
12
13
|
*
|
|
@@ -23,9 +24,10 @@
|
|
|
23
24
|
*/
|
|
24
25
|
import { ComponentVars } from '../types';
|
|
25
26
|
import { INJECT_COMPONENTS, ensureInjectConfig } from '../constants';
|
|
26
|
-
import { provide } from 'vue';
|
|
27
|
+
import { computed, provide } from 'vue';
|
|
27
28
|
import { getObject } from '../../../shared/core';
|
|
28
29
|
import { ComponentName } from '../../form/constants';
|
|
30
|
+
import { LOCALE_INJECT_KEY, type ProLocale } from '../../../locale';
|
|
29
31
|
|
|
30
32
|
type ComponentMap = Partial<Record<ComponentName, any>>;
|
|
31
33
|
|
|
@@ -39,6 +41,11 @@ type Props = {
|
|
|
39
41
|
componentVars?: ComponentVars;
|
|
40
42
|
/** 自定义组件映射,用于替换或扩展内置组件 */
|
|
41
43
|
componentMap?: ComponentMap;
|
|
44
|
+
/**
|
|
45
|
+
* 内置文案覆盖,可覆盖任意 locale 文案(如查询/重置/序号/占位符等),
|
|
46
|
+
* 未覆盖的文案默认跟随宿主组件库语言自动切换
|
|
47
|
+
*/
|
|
48
|
+
locale?: Partial<ProLocale>;
|
|
42
49
|
};
|
|
43
50
|
|
|
44
51
|
const props = defineProps<Props>();
|
|
@@ -60,6 +67,12 @@ if (props.componentVars) {
|
|
|
60
67
|
if (props.componentMap) {
|
|
61
68
|
provide(INJECT_COMPONENTS, props.componentMap);
|
|
62
69
|
}
|
|
70
|
+
|
|
71
|
+
// 注入内置文案覆盖,useLocale 在解析文案时会优先使用
|
|
72
|
+
provide(
|
|
73
|
+
LOCALE_INJECT_KEY,
|
|
74
|
+
computed(() => props.locale)
|
|
75
|
+
);
|
|
63
76
|
</script>
|
|
64
77
|
|
|
65
78
|
<template>
|
|
@@ -38,7 +38,7 @@ export const INJECT_CONFIG: {
|
|
|
38
38
|
},
|
|
39
39
|
input: {
|
|
40
40
|
injectionKey: Symbol(''),
|
|
41
|
-
default: { maxlength: 100, clearable: true
|
|
41
|
+
default: { maxlength: 100, clearable: true },
|
|
42
42
|
},
|
|
43
43
|
'input.textarea': {
|
|
44
44
|
injectionKey: Symbol(''),
|
|
@@ -47,7 +47,6 @@ export const INJECT_CONFIG: {
|
|
|
47
47
|
autosize: { minRows: 3, maxRows: 6 },
|
|
48
48
|
showWordLimit: true,
|
|
49
49
|
clearable: true,
|
|
50
|
-
placeholder: '请输入',
|
|
51
50
|
},
|
|
52
51
|
},
|
|
53
52
|
'input.password': {
|
|
@@ -56,7 +55,6 @@ export const INJECT_CONFIG: {
|
|
|
56
55
|
showPassword: true,
|
|
57
56
|
maxlength: 100,
|
|
58
57
|
clearable: true,
|
|
59
|
-
placeholder: '请输入',
|
|
60
58
|
},
|
|
61
59
|
},
|
|
62
60
|
'input-number': {
|
|
@@ -65,97 +63,80 @@ export const INJECT_CONFIG: {
|
|
|
65
63
|
max: 10 ** 15 - 1,
|
|
66
64
|
min: -(10 ** 15 + 1),
|
|
67
65
|
controls: false,
|
|
68
|
-
placeholder: '请输入',
|
|
69
66
|
style: { width: '100%' },
|
|
70
67
|
},
|
|
71
68
|
},
|
|
72
69
|
autocomplete: {
|
|
73
70
|
injectionKey: Symbol(''),
|
|
74
|
-
default: { clearable: true
|
|
71
|
+
default: { clearable: true },
|
|
75
72
|
},
|
|
76
73
|
select: {
|
|
77
74
|
injectionKey: Symbol(''),
|
|
78
|
-
default: { clearable: true
|
|
75
|
+
default: { clearable: true },
|
|
79
76
|
},
|
|
80
77
|
cascader: {
|
|
81
78
|
injectionKey: Symbol(''),
|
|
82
|
-
default: { clearable: true
|
|
79
|
+
default: { clearable: true },
|
|
83
80
|
},
|
|
84
81
|
'date-picker': {
|
|
85
82
|
injectionKey: Symbol(''),
|
|
86
|
-
default: { style: { width: '100%' }
|
|
83
|
+
default: { style: { width: '100%' } },
|
|
87
84
|
},
|
|
88
85
|
'date-picker.date': {
|
|
89
86
|
injectionKey: Symbol(''),
|
|
90
|
-
default: { style: { width: '100%' }
|
|
87
|
+
default: { style: { width: '100%' } },
|
|
91
88
|
},
|
|
92
89
|
'date-picker.dates': {
|
|
93
90
|
injectionKey: Symbol(''),
|
|
94
|
-
default: { style: { width: '100%' }
|
|
91
|
+
default: { style: { width: '100%' } },
|
|
95
92
|
},
|
|
96
93
|
'date-picker.daterange': {
|
|
97
94
|
injectionKey: Symbol(''),
|
|
98
|
-
default: {
|
|
99
|
-
style: { width: '100%' },
|
|
100
|
-
startPlaceholder: '开始日期',
|
|
101
|
-
endPlaceholder: '结束日期',
|
|
102
|
-
},
|
|
95
|
+
default: { style: { width: '100%' } },
|
|
103
96
|
},
|
|
104
97
|
'date-picker.week': {
|
|
105
98
|
injectionKey: Symbol(''),
|
|
106
|
-
default: { style: { width: '100%' }
|
|
99
|
+
default: { style: { width: '100%' } },
|
|
107
100
|
},
|
|
108
101
|
'date-picker.month': {
|
|
109
102
|
injectionKey: Symbol(''),
|
|
110
|
-
default: { style: { width: '100%' }
|
|
103
|
+
default: { style: { width: '100%' } },
|
|
111
104
|
},
|
|
112
105
|
'date-picker.monthrange': {
|
|
113
106
|
injectionKey: Symbol(''),
|
|
114
|
-
default: {
|
|
115
|
-
style: { width: '100%' },
|
|
116
|
-
startPlaceholder: '开始月份',
|
|
117
|
-
endPlaceholder: '结束月份',
|
|
118
|
-
},
|
|
107
|
+
default: { style: { width: '100%' } },
|
|
119
108
|
},
|
|
120
109
|
'date-picker.months': {
|
|
121
110
|
injectionKey: Symbol(''),
|
|
122
|
-
default: { style: { width: '100%' }
|
|
111
|
+
default: { style: { width: '100%' } },
|
|
123
112
|
},
|
|
124
113
|
'date-picker.yearrange': {
|
|
125
114
|
injectionKey: Symbol(''),
|
|
126
|
-
default: {
|
|
127
|
-
style: { width: '100%' },
|
|
128
|
-
startPlaceholder: '开始年份',
|
|
129
|
-
endPlaceholder: '结束年份',
|
|
130
|
-
},
|
|
115
|
+
default: { style: { width: '100%' } },
|
|
131
116
|
},
|
|
132
117
|
'date-picker.year': {
|
|
133
118
|
injectionKey: Symbol(''),
|
|
134
|
-
default: { style: { width: '100%' }
|
|
119
|
+
default: { style: { width: '100%' } },
|
|
135
120
|
},
|
|
136
121
|
'date-picker.years': {
|
|
137
122
|
injectionKey: Symbol(''),
|
|
138
|
-
default: { style: { width: '100%' }
|
|
123
|
+
default: { style: { width: '100%' } },
|
|
139
124
|
},
|
|
140
125
|
'date-picker.datetime': {
|
|
141
126
|
injectionKey: Symbol(''),
|
|
142
|
-
default: { style: { width: '100%' }
|
|
127
|
+
default: { style: { width: '100%' } },
|
|
143
128
|
},
|
|
144
129
|
'date-picker.datetimerange': {
|
|
145
130
|
injectionKey: Symbol(''),
|
|
146
|
-
default: {
|
|
147
|
-
style: { width: '100%' },
|
|
148
|
-
startPlaceholder: '开始时间',
|
|
149
|
-
endPlaceholder: '结束时间',
|
|
150
|
-
},
|
|
131
|
+
default: { style: { width: '100%' } },
|
|
151
132
|
},
|
|
152
133
|
'time-picker': {
|
|
153
134
|
injectionKey: Symbol(''),
|
|
154
|
-
default: { style: { width: '100%' }
|
|
135
|
+
default: { style: { width: '100%' } },
|
|
155
136
|
},
|
|
156
137
|
'time-select': {
|
|
157
138
|
injectionKey: Symbol(''),
|
|
158
|
-
default: { style: { width: '100%' }
|
|
139
|
+
default: { style: { width: '100%' } },
|
|
159
140
|
},
|
|
160
141
|
'checkbox-group': {
|
|
161
142
|
injectionKey: Symbol(''),
|
|
@@ -175,7 +156,7 @@ export const INJECT_CONFIG: {
|
|
|
175
156
|
},
|
|
176
157
|
'tree-select': {
|
|
177
158
|
injectionKey: Symbol(''),
|
|
178
|
-
default: { clearable: true
|
|
159
|
+
default: { clearable: true },
|
|
179
160
|
},
|
|
180
161
|
transfer: {
|
|
181
162
|
injectionKey: Symbol(''),
|
|
@@ -43,6 +43,7 @@ import { componentMap, TeleportComponentNamePrefix } from '../../constants';
|
|
|
43
43
|
import { INJECT_COMPONENTS } from '../../../component-provider/constants';
|
|
44
44
|
import { useForm } from '../../hooks/useForm';
|
|
45
45
|
import { getInitProps } from './utils';
|
|
46
|
+
import { useLocale } from '../../../../locale';
|
|
46
47
|
|
|
47
48
|
defineOptions({ name: 'BaseField', inheritAttrs: false });
|
|
48
49
|
|
|
@@ -52,6 +53,8 @@ type Props = {
|
|
|
52
53
|
};
|
|
53
54
|
const { component = undefined, path = '' } = defineProps<Props>();
|
|
54
55
|
|
|
56
|
+
const { t } = useLocale();
|
|
57
|
+
|
|
55
58
|
const form = useForm(false);
|
|
56
59
|
const { getFormData, setFormData } = form;
|
|
57
60
|
|
|
@@ -97,10 +100,13 @@ const parentDisabled = useDisabledContext();
|
|
|
97
100
|
* 属性分为三类:绑定属性(v-model)、组件属性(传递给组件)、插槽(动态渲染)
|
|
98
101
|
*/
|
|
99
102
|
const groupedAttrs = computed(() => {
|
|
100
|
-
const initProps = getInitProps(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
const initProps = getInitProps(
|
|
104
|
+
{
|
|
105
|
+
component: component,
|
|
106
|
+
type: attrs.type,
|
|
107
|
+
} as unknown as Field,
|
|
108
|
+
t
|
|
109
|
+
);
|
|
104
110
|
const modelPropName = attrs.modelProp ?? initProps.modelProp ?? 'modelValue';
|
|
105
111
|
const mergedProps = mergeProps(
|
|
106
112
|
initProps,
|
|
@@ -2,14 +2,77 @@ import { Field } from '../../../types';
|
|
|
2
2
|
import { getInjectConfig } from '../../../../component-provider/constants';
|
|
3
3
|
import { inject } from 'vue';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
type LocaleT = (
|
|
6
|
+
key: string,
|
|
7
|
+
params?: Record<string, string | number>
|
|
8
|
+
) => string;
|
|
9
|
+
|
|
10
|
+
/** 单值组件的占位符对应的 locale key */
|
|
11
|
+
const PLACEHOLDER_KEYS: Record<string, string> = {
|
|
12
|
+
input: 'input.placeholder',
|
|
13
|
+
'input.textarea': 'input.placeholder',
|
|
14
|
+
'input.password': 'input.placeholder',
|
|
15
|
+
'input-number': 'input.placeholder',
|
|
16
|
+
autocomplete: 'input.placeholder',
|
|
17
|
+
select: 'select.placeholder',
|
|
18
|
+
cascader: 'select.placeholder',
|
|
19
|
+
'tree-select': 'select.placeholder',
|
|
20
|
+
'date-picker': 'date-picker.placeholder',
|
|
21
|
+
'date-picker.date': 'date-picker.placeholder',
|
|
22
|
+
'date-picker.dates': 'date-picker.placeholder',
|
|
23
|
+
'date-picker.week': 'date-picker.placeholder',
|
|
24
|
+
'date-picker.month': 'date-picker.placeholder',
|
|
25
|
+
'date-picker.months': 'date-picker.placeholder',
|
|
26
|
+
'date-picker.year': 'date-picker.placeholder',
|
|
27
|
+
'date-picker.years': 'date-picker.placeholder',
|
|
28
|
+
'date-picker.datetime': 'date-picker.placeholder',
|
|
29
|
+
'time-picker': 'date-picker.placeholder',
|
|
30
|
+
'time-select': 'date-picker.placeholder',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/** 区间组件 start/end 占位符对应的 locale key */
|
|
34
|
+
const RANGE_PLACEHOLDER_KEYS: Record<string, [string, string]> = {
|
|
35
|
+
'date-picker.daterange': ['date-picker.start', 'date-picker.end'],
|
|
36
|
+
'date-picker.monthrange': ['date-picker.startMonth', 'date-picker.endMonth'],
|
|
37
|
+
'date-picker.yearrange': ['date-picker.startYear', 'date-picker.endYear'],
|
|
38
|
+
'date-picker.datetimerange': ['date-picker.startTime', 'date-picker.endTime'],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 根据组件 key 兜底生成 locale 占位符
|
|
43
|
+
*
|
|
44
|
+
* @description 用户通过 componentVars 或字段属性显式设置了占位符时不再兜底。
|
|
45
|
+
*/
|
|
46
|
+
const getPlaceholderProps = (
|
|
47
|
+
key: string,
|
|
48
|
+
injectProps: Record<string, any>,
|
|
49
|
+
t: LocaleT
|
|
50
|
+
): Record<string, string> => {
|
|
51
|
+
const rangeKeys = RANGE_PLACEHOLDER_KEYS[key];
|
|
52
|
+
if (rangeKeys) {
|
|
53
|
+
if (
|
|
54
|
+
injectProps.startPlaceholder !== undefined ||
|
|
55
|
+
injectProps.placeholder !== undefined
|
|
56
|
+
)
|
|
57
|
+
return {};
|
|
58
|
+
return {
|
|
59
|
+
startPlaceholder: t(rangeKeys[0]),
|
|
60
|
+
endPlaceholder: t(rangeKeys[1]),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const placeholderKey = PLACEHOLDER_KEYS[key];
|
|
64
|
+
if (!placeholderKey || injectProps.placeholder !== undefined) return {};
|
|
65
|
+
return { placeholder: t(placeholderKey) };
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const getInitProps = (field: Field, t: LocaleT): Record<string, any> => {
|
|
6
69
|
const { component, type } = field as any;
|
|
7
70
|
if (typeof component === 'string') {
|
|
8
71
|
const k = [component, type].filter(Boolean).join('.');
|
|
9
72
|
const config = getInjectConfig(k);
|
|
10
|
-
if (!config) return {};
|
|
73
|
+
if (!config) return getPlaceholderProps(k, {}, t);
|
|
11
74
|
const injectProps = inject(config.injectionKey, config.default);
|
|
12
|
-
return injectProps;
|
|
75
|
+
return { ...injectProps, ...getPlaceholderProps(k, injectProps, t) };
|
|
13
76
|
}
|
|
14
77
|
return {};
|
|
15
78
|
};
|
|
@@ -6,16 +6,24 @@ import {
|
|
|
6
6
|
DropdownItem,
|
|
7
7
|
Checkbox,
|
|
8
8
|
} from '../../../shared/ui';
|
|
9
|
-
import { computed, ref, watch } from 'vue';
|
|
10
|
-
import type { Column, Columns } from '../types';
|
|
9
|
+
import { computed, onMounted, ref, watch } from 'vue';
|
|
10
|
+
import type { Column, Columns, ColumnControlConfig } from '../types';
|
|
11
11
|
import { type Table } from '../useTable';
|
|
12
12
|
import FilterOutlined from './icons/FilterOutlined.vue';
|
|
13
|
+
import { useLocale } from '../../../locale';
|
|
13
14
|
|
|
14
15
|
type Props = {
|
|
15
16
|
columns: Columns;
|
|
16
17
|
table?: Table;
|
|
18
|
+
columnControl?: ColumnControlConfig;
|
|
17
19
|
};
|
|
18
|
-
const {
|
|
20
|
+
const {
|
|
21
|
+
columns,
|
|
22
|
+
table = undefined,
|
|
23
|
+
columnControl = undefined,
|
|
24
|
+
} = defineProps<Props>();
|
|
25
|
+
|
|
26
|
+
const { t } = useLocale();
|
|
19
27
|
|
|
20
28
|
const open = ref(false);
|
|
21
29
|
const checkAll = ref(false);
|
|
@@ -28,14 +36,43 @@ const getColumnKey = (column: Column, index: number) => {
|
|
|
28
36
|
};
|
|
29
37
|
|
|
30
38
|
const checkedColumnsOptions = computed<
|
|
31
|
-
Array<{
|
|
39
|
+
Array<{
|
|
40
|
+
label: string;
|
|
41
|
+
value: string;
|
|
42
|
+
checked: boolean;
|
|
43
|
+
disabled: boolean;
|
|
44
|
+
column: Column;
|
|
45
|
+
}>
|
|
32
46
|
>(() =>
|
|
33
|
-
columns
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
47
|
+
columns
|
|
48
|
+
.map((item, index) => {
|
|
49
|
+
const key = getColumnKey(item, index);
|
|
50
|
+
const excluded = columnControl?.excludedKeys?.some(
|
|
51
|
+
ek => String(ek) === key
|
|
52
|
+
);
|
|
53
|
+
const disabled = columnControl?.disabledKeys?.some(
|
|
54
|
+
dk => String(dk) === key
|
|
55
|
+
);
|
|
56
|
+
const label = String(
|
|
57
|
+
item.label ??
|
|
58
|
+
item.prop ??
|
|
59
|
+
t('table.columnFallback', { index: index + 1 })
|
|
60
|
+
);
|
|
61
|
+
return {
|
|
62
|
+
label,
|
|
63
|
+
value: key,
|
|
64
|
+
checked: !item.hidden || !!disabled,
|
|
65
|
+
disabled: !!disabled,
|
|
66
|
+
column: item,
|
|
67
|
+
excluded,
|
|
68
|
+
};
|
|
69
|
+
})
|
|
70
|
+
.filter(item => !item.excluded)
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
/** 可被用户勾选/取消的列(非 disabled) */
|
|
74
|
+
const controllableOptions = computed(() =>
|
|
75
|
+
checkedColumnsOptions.value.filter(item => !item.disabled)
|
|
39
76
|
);
|
|
40
77
|
|
|
41
78
|
const checkedColumnKeys = computed({
|
|
@@ -46,6 +83,7 @@ const checkedColumnKeys = computed({
|
|
|
46
83
|
},
|
|
47
84
|
set(val: string[]) {
|
|
48
85
|
checkedColumnsOptions.value.forEach(item => {
|
|
86
|
+
if (item.disabled) return;
|
|
49
87
|
table?.setColumn(item.value as any, {
|
|
50
88
|
hidden: !val.includes(item.value),
|
|
51
89
|
});
|
|
@@ -56,12 +94,14 @@ const checkedColumnKeys = computed({
|
|
|
56
94
|
const onCheckAllChange = (value: any) => {
|
|
57
95
|
const checked = !!(value?.target?.checked ?? value);
|
|
58
96
|
checkedColumnKeys.value = checked
|
|
59
|
-
?
|
|
97
|
+
? controllableOptions.value.map(item => item.value)
|
|
60
98
|
: [];
|
|
61
99
|
indeterminate.value = false;
|
|
62
100
|
};
|
|
63
101
|
|
|
64
102
|
const toggleColumnsItem = (val: string) => {
|
|
103
|
+
const item = checkedColumnsOptions.value.find(o => o.value === val);
|
|
104
|
+
if (item?.disabled) return;
|
|
65
105
|
if (checkedColumnKeys.value.includes(val)) {
|
|
66
106
|
checkedColumnKeys.value = checkedColumnKeys.value.filter(
|
|
67
107
|
item => item !== val
|
|
@@ -73,14 +113,36 @@ const toggleColumnsItem = (val: string) => {
|
|
|
73
113
|
|
|
74
114
|
watch(
|
|
75
115
|
checkedColumnKeys,
|
|
76
|
-
|
|
116
|
+
() => {
|
|
117
|
+
const controllableChecked = controllableOptions.value.filter(
|
|
118
|
+
item => item.checked
|
|
119
|
+
);
|
|
77
120
|
indeterminate.value =
|
|
78
|
-
!!
|
|
121
|
+
!!controllableChecked.length &&
|
|
122
|
+
controllableChecked.length < controllableOptions.value.length;
|
|
79
123
|
checkAll.value =
|
|
80
|
-
|
|
124
|
+
controllableChecked.length === controllableOptions.value.length &&
|
|
125
|
+
controllableOptions.value.length > 0;
|
|
81
126
|
},
|
|
82
127
|
{ immediate: true }
|
|
83
128
|
);
|
|
129
|
+
|
|
130
|
+
// 强制 disabledKeys 列始终展示
|
|
131
|
+
onMounted(() => {
|
|
132
|
+
columnControl?.disabledKeys?.forEach(key => {
|
|
133
|
+
table?.setColumn(String(key), { hidden: false });
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
watch(
|
|
138
|
+
() => columnControl?.disabledKeys,
|
|
139
|
+
keys => {
|
|
140
|
+
keys?.forEach(key => {
|
|
141
|
+
table?.setColumn(String(key), { hidden: false });
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
{ deep: true }
|
|
145
|
+
);
|
|
84
146
|
</script>
|
|
85
147
|
|
|
86
148
|
<template>
|
|
@@ -95,13 +157,17 @@ watch(
|
|
|
95
157
|
</Button>
|
|
96
158
|
<template #dropdown>
|
|
97
159
|
<DropdownMenu>
|
|
98
|
-
<DropdownItem
|
|
160
|
+
<DropdownItem
|
|
161
|
+
v-if="!columnControl?.disableCheckAll"
|
|
162
|
+
:disabled="true"
|
|
163
|
+
:divided="false"
|
|
164
|
+
>
|
|
99
165
|
<Checkbox
|
|
100
166
|
:model-value="checkAll"
|
|
101
167
|
:indeterminate="indeterminate"
|
|
102
168
|
@change="onCheckAllChange"
|
|
103
169
|
>
|
|
104
|
-
|
|
170
|
+
{{ t('table.selectAll') }}
|
|
105
171
|
</Checkbox>
|
|
106
172
|
</DropdownItem>
|
|
107
173
|
<DropdownItem
|
|
@@ -110,10 +176,7 @@ watch(
|
|
|
110
176
|
:command="item.value"
|
|
111
177
|
@click.stop="toggleColumnsItem(item.value)"
|
|
112
178
|
>
|
|
113
|
-
<Checkbox
|
|
114
|
-
:model-value="item.checked"
|
|
115
|
-
@change="() => toggleColumnsItem(item.value)"
|
|
116
|
-
>
|
|
179
|
+
<Checkbox :model-value="item.checked" :disabled="item.disabled">
|
|
117
180
|
{{ item.label }}
|
|
118
181
|
</Checkbox>
|
|
119
182
|
</DropdownItem>
|