@tmagic/form 1.6.0 → 1.7.0-beta.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/dist/style.css +29 -3
- package/dist/tmagic-form.js +1788 -1581
- package/dist/tmagic-form.umd.cjs +1830 -1619
- package/package.json +6 -6
- package/src/Form.vue +18 -5
- package/src/containers/Container.vue +109 -134
- package/src/containers/Fieldset.vue +31 -7
- package/src/containers/FlexLayout.vue +59 -0
- package/src/containers/Tabs.vue +11 -1
- package/src/fields/Cascader.vue +25 -16
- package/src/fields/Checkbox.vue +3 -3
- package/src/fields/CheckboxGroup.vue +1 -1
- package/src/fields/ColorPicker.vue +2 -2
- package/src/fields/Date.vue +2 -2
- package/src/fields/DateTime.vue +2 -2
- package/src/fields/Daterange.vue +2 -2
- package/src/fields/Number.vue +2 -2
- package/src/fields/NumberRange.vue +6 -6
- package/src/fields/RadioGroup.vue +18 -16
- package/src/fields/Select.vue +2 -2
- package/src/fields/Switch.vue +2 -2
- package/src/fields/Text.vue +21 -9
- package/src/fields/Textarea.vue +2 -2
- package/src/fields/Time.vue +2 -2
- package/src/fields/Timerange.vue +2 -2
- package/src/index.ts +5 -2
- package/src/table/ActionsColumn.vue +97 -0
- package/src/table/SortColumn.vue +101 -0
- package/src/table/Table.vue +170 -0
- package/src/table/type.ts +18 -0
- package/src/table/useAdd.ts +111 -0
- package/src/table/useFullscreen.ts +28 -0
- package/src/table/useImport.ts +68 -0
- package/src/table/usePagination.ts +30 -0
- package/src/table/useSelection.ts +34 -0
- package/src/table/useSortable.ts +48 -0
- package/src/table/useTableColumns.ts +194 -0
- package/src/theme/container.scss +17 -0
- package/src/theme/form.scss +15 -3
- package/src/theme/text.scss +6 -0
- package/src/utils/form.ts +56 -2
- package/types/index.d.ts +103 -56
- package/src/containers/Table.vue +0 -681
package/src/fields/Checkbox.vue
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TMagicCheckbox
|
|
3
|
-
|
|
3
|
+
:model-value="model[name]"
|
|
4
4
|
:size="size"
|
|
5
5
|
:trueValue="activeValue"
|
|
6
6
|
:falseValue="inactiveValue"
|
|
7
7
|
:disabled="disabled"
|
|
8
|
-
@
|
|
9
|
-
>{{ config.text }}</TMagicCheckbox
|
|
8
|
+
@update:model-value="changeHandler"
|
|
9
|
+
><template #default v-if="!config.useLabel">{{ config.text }}</template></TMagicCheckbox
|
|
10
10
|
>
|
|
11
11
|
</template>
|
|
12
12
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<TMagicCheckboxGroup
|
|
2
|
+
<TMagicCheckboxGroup :model-value="model[name]" :size="size" :disabled="disabled" @update:model-value="changeHandler">
|
|
3
3
|
<TMagicCheckbox v-for="option in options" :value="option.value" :key="option.value" :disabled="option.disabled"
|
|
4
4
|
>{{ option.text }}
|
|
5
5
|
</TMagicCheckbox>
|
package/src/fields/Date.vue
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TMagicDatePicker
|
|
3
|
-
|
|
3
|
+
:model-value="model[name]"
|
|
4
4
|
type="date"
|
|
5
5
|
:size="size"
|
|
6
6
|
:placeholder="config.placeholder"
|
|
7
7
|
:disabled="disabled"
|
|
8
8
|
:format="config.format || 'YYYY/MM/DD'"
|
|
9
9
|
:value-format="config.valueFormat || 'YYYY/MM/DD'"
|
|
10
|
-
@
|
|
10
|
+
@update:model-value="changeHandler"
|
|
11
11
|
></TMagicDatePicker>
|
|
12
12
|
</template>
|
|
13
13
|
|
package/src/fields/DateTime.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TMagicDatePicker
|
|
3
|
-
|
|
3
|
+
:model-value="model[name]"
|
|
4
4
|
popper-class="magic-datetime-picker-popper"
|
|
5
5
|
type="datetime"
|
|
6
6
|
:size="size"
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
:format="config.format || 'YYYY/MM/DD HH:mm:ss'"
|
|
10
10
|
:value-format="config.valueFormat || 'YYYY/MM/DD HH:mm:ss'"
|
|
11
11
|
:default-time="config.defaultTime"
|
|
12
|
-
@
|
|
12
|
+
@update:model-value="changeHandler"
|
|
13
13
|
></TMagicDatePicker>
|
|
14
14
|
</template>
|
|
15
15
|
|
package/src/fields/Daterange.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TMagicDatePicker
|
|
3
|
-
|
|
3
|
+
:model-value="value"
|
|
4
4
|
type="datetimerange"
|
|
5
5
|
range-separator="-"
|
|
6
6
|
start-placeholder="开始日期"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
:value-format="config.valueFormat || 'YYYY/MM/DD HH:mm:ss'"
|
|
13
13
|
:date-format="config.dateFormat || 'YYYY/MM/DD'"
|
|
14
14
|
:time-format="config.timeFormat || 'HH:mm:ss'"
|
|
15
|
-
@
|
|
15
|
+
@update:model-value="changeHandler"
|
|
16
16
|
></TMagicDatePicker>
|
|
17
17
|
</template>
|
|
18
18
|
|
package/src/fields/Number.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TMagicInputNumber
|
|
3
3
|
v-if="model"
|
|
4
|
-
|
|
4
|
+
:model-value="model[name]"
|
|
5
5
|
clearable
|
|
6
6
|
controls-position="right"
|
|
7
7
|
:size="size"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
:step="config.step"
|
|
11
11
|
:placeholder="config.placeholder"
|
|
12
12
|
:disabled="disabled"
|
|
13
|
-
@
|
|
13
|
+
@update:model-value="changeHandler"
|
|
14
14
|
@input="inputHandler"
|
|
15
15
|
></TMagicInputNumber>
|
|
16
16
|
</template>
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-fields-number-range">
|
|
3
3
|
<TMagicInput
|
|
4
|
-
|
|
5
|
-
clearable
|
|
4
|
+
:model-value="model[name][0]"
|
|
5
|
+
:clearable="config.clearable ?? true"
|
|
6
6
|
:size="size"
|
|
7
7
|
:disabled="disabled"
|
|
8
|
-
@
|
|
8
|
+
@update:model-value="minChangeHandler"
|
|
9
9
|
></TMagicInput>
|
|
10
10
|
<span class="split-tag">-</span>
|
|
11
11
|
<TMagicInput
|
|
12
|
-
|
|
13
|
-
clearable
|
|
12
|
+
:model-value="model[name][1]"
|
|
13
|
+
:clearable="config.clearable ?? true"
|
|
14
14
|
:size="size"
|
|
15
15
|
:disabled="disabled"
|
|
16
|
-
@
|
|
16
|
+
@update:model-value="maxChangeHandler"
|
|
17
17
|
></TMagicInput>
|
|
18
18
|
</div>
|
|
19
19
|
</template>
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<TMagicRadioGroup v-if="model"
|
|
2
|
+
<TMagicRadioGroup v-if="model" :model-value="model[name]" :size="size" :disabled="disabled">
|
|
3
3
|
<component
|
|
4
|
-
:is="itemComponent"
|
|
5
4
|
v-for="option in config.options"
|
|
5
|
+
:is="itemComponent"
|
|
6
6
|
:value="option.value"
|
|
7
7
|
:key="`${option.value}`"
|
|
8
|
-
@click
|
|
8
|
+
@click="clickHandler(option.value)"
|
|
9
9
|
>
|
|
10
|
-
<TMagicTooltip
|
|
10
|
+
<TMagicTooltip :disabled="!Boolean(option.tooltip)" placement="top-start" :content="option.tooltip">
|
|
11
11
|
<div>
|
|
12
|
-
<TMagicIcon v-if="option.icon" :size="
|
|
12
|
+
<TMagicIcon v-if="option.icon" :size="iconSize"><component :is="option.icon"></component></TMagicIcon>
|
|
13
13
|
<span>{{ option.text }}</span>
|
|
14
14
|
</div>
|
|
15
15
|
</TMagicTooltip>
|
|
16
|
-
<div v-else>
|
|
17
|
-
<TMagicIcon v-if="option.icon" :size="'16'"><component :is="option.icon"></component></TMagicIcon>
|
|
18
|
-
<span>{{ option.text }}</span>
|
|
19
|
-
</div>
|
|
20
16
|
</component>
|
|
21
17
|
</TMagicRadioGroup>
|
|
22
18
|
</template>
|
|
@@ -39,14 +35,20 @@ const itemComponent = computed(() => (props.config.childType === 'button' ? TMag
|
|
|
39
35
|
|
|
40
36
|
const emit = defineEmits(['change']);
|
|
41
37
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const clickHandler = (item: any) => {
|
|
47
|
-
props.model[props.name] = props.model[props.name] === item ? '' : item;
|
|
48
|
-
changeHandler(props.model[props.name]);
|
|
38
|
+
const clickHandler = (item: string | number | boolean) => {
|
|
39
|
+
// 再次点击取消选中
|
|
40
|
+
emit('change', props.model[props.name] === item ? '' : item);
|
|
49
41
|
};
|
|
50
42
|
|
|
51
43
|
useAddField(props.prop);
|
|
44
|
+
|
|
45
|
+
const iconSize = computed(() => {
|
|
46
|
+
if (props.size === 'small') {
|
|
47
|
+
return '12';
|
|
48
|
+
}
|
|
49
|
+
if (props.size === 'large') {
|
|
50
|
+
return '16';
|
|
51
|
+
}
|
|
52
|
+
return '14';
|
|
53
|
+
});
|
|
52
54
|
</script>
|
package/src/fields/Select.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TMagicSelect
|
|
3
3
|
v-if="model"
|
|
4
|
-
|
|
4
|
+
:model-value="model[name]"
|
|
5
5
|
v-loading="loading"
|
|
6
6
|
class="m-select"
|
|
7
7
|
ref="tMagicSelect"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
:allow-create="config.allowCreate"
|
|
17
17
|
:disabled="disabled"
|
|
18
18
|
:remote-method="config.remote && remoteMethod"
|
|
19
|
-
@
|
|
19
|
+
@update:model-value="changeHandler"
|
|
20
20
|
@visible-change="visibleHandler"
|
|
21
21
|
>
|
|
22
22
|
<template v-if="config.group">
|
package/src/fields/Switch.vue
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TMagicSwitch
|
|
3
|
-
|
|
3
|
+
:model-value="model[name]"
|
|
4
4
|
:size="size"
|
|
5
5
|
:activeValue="activeValue"
|
|
6
6
|
:inactiveValue="inactiveValue"
|
|
7
7
|
:disabled="disabled"
|
|
8
|
-
@
|
|
8
|
+
@update:model-value="changeHandler"
|
|
9
9
|
></TMagicSwitch>
|
|
10
10
|
</template>
|
|
11
11
|
|
package/src/fields/Text.vue
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div class="m-fields-text">
|
|
3
3
|
<TMagicInput
|
|
4
|
-
|
|
4
|
+
:model-value="model[name]"
|
|
5
5
|
ref="input"
|
|
6
6
|
clearable
|
|
7
7
|
:size="size"
|
|
8
8
|
:placeholder="config.placeholder"
|
|
9
9
|
:disabled="disabled"
|
|
10
|
-
@
|
|
10
|
+
@update:model-value="changeHandler"
|
|
11
11
|
@input="inputHandler"
|
|
12
12
|
@keyup="keyUpHandler($event)"
|
|
13
13
|
>
|
|
14
|
+
<template #prepend v-if="config.prepend">
|
|
15
|
+
<span>{{ config.prepend }}</span>
|
|
16
|
+
</template>
|
|
14
17
|
<template #append v-if="appendConfig">
|
|
15
18
|
<TMagicButton
|
|
16
19
|
v-if="appendConfig.type === 'button'"
|
|
@@ -20,6 +23,7 @@
|
|
|
20
23
|
>
|
|
21
24
|
{{ appendConfig.text }}
|
|
22
25
|
</TMagicButton>
|
|
26
|
+
<span v-else>{{ appendConfig.text }}</span>
|
|
23
27
|
</template>
|
|
24
28
|
</TMagicInput>
|
|
25
29
|
|
|
@@ -66,18 +70,26 @@ const mForm = inject<FormState | undefined>('mForm');
|
|
|
66
70
|
const appendConfig = computed(() => {
|
|
67
71
|
if (typeof props.config.append === 'string') {
|
|
68
72
|
return {
|
|
73
|
+
type: 'text',
|
|
69
74
|
text: props.config.append,
|
|
70
|
-
type: 'button',
|
|
71
75
|
handler: undefined,
|
|
72
76
|
};
|
|
73
77
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
if (typeof props.config.append === 'object') {
|
|
79
|
+
if (typeof props.config.append?.handler === 'function') {
|
|
80
|
+
return {
|
|
81
|
+
type: 'button',
|
|
82
|
+
text: props.config.append.text,
|
|
83
|
+
handler: props.config.append.handler,
|
|
84
|
+
};
|
|
78
85
|
}
|
|
86
|
+
if (props.config.append) {
|
|
87
|
+
if (props.config.append.value === 0) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
79
90
|
|
|
80
|
-
|
|
91
|
+
return props.config.append;
|
|
92
|
+
}
|
|
81
93
|
}
|
|
82
94
|
|
|
83
95
|
return false;
|
package/src/fields/Textarea.vue
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TMagicInput
|
|
3
|
-
|
|
3
|
+
:model-value="model[name]"
|
|
4
4
|
type="textarea"
|
|
5
5
|
:size="size"
|
|
6
6
|
clearable
|
|
7
7
|
:placeholder="config.placeholder"
|
|
8
8
|
:disabled="disabled"
|
|
9
|
-
@
|
|
9
|
+
@update:model-value="changeHandler"
|
|
10
10
|
@input="inputHandler"
|
|
11
11
|
>
|
|
12
12
|
</TMagicInput>
|
package/src/fields/Time.vue
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TMagicTimePicker
|
|
3
|
-
|
|
3
|
+
:model-value="model[name]"
|
|
4
4
|
:value-format="config.valueFormat || 'HH:mm:ss'"
|
|
5
5
|
:format="config.format || 'HH:mm:ss'"
|
|
6
6
|
:size="size"
|
|
7
7
|
:placeholder="config.placeholder"
|
|
8
8
|
:disabled="disabled"
|
|
9
|
-
@
|
|
9
|
+
@update:model-value="changeHandler"
|
|
10
10
|
></TMagicTimePicker>
|
|
11
11
|
</template>
|
|
12
12
|
|
package/src/fields/Timerange.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TMagicTimePicker
|
|
3
|
-
|
|
3
|
+
:model-value="value"
|
|
4
4
|
is-range
|
|
5
5
|
range-separator="-"
|
|
6
6
|
start-placeholder="开始时间"
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
:unlink-panels="true"
|
|
10
10
|
:disabled="disabled"
|
|
11
11
|
:default-time="config.defaultTime"
|
|
12
|
-
@
|
|
12
|
+
@update:model-value="changeHandler"
|
|
13
13
|
></TMagicTimePicker>
|
|
14
14
|
</template>
|
|
15
15
|
|
package/src/index.ts
CHANGED
|
@@ -20,11 +20,11 @@ import type { App } from 'vue';
|
|
|
20
20
|
|
|
21
21
|
import Container from './containers/Container.vue';
|
|
22
22
|
import Fieldset from './containers/Fieldset.vue';
|
|
23
|
+
import FlexLayout from './containers/FlexLayout.vue';
|
|
23
24
|
import GroupList from './containers/GroupList.vue';
|
|
24
25
|
import Panel from './containers/Panel.vue';
|
|
25
26
|
import Row from './containers/Row.vue';
|
|
26
27
|
import MStep from './containers/Step.vue';
|
|
27
|
-
import Table from './containers/Table.vue';
|
|
28
28
|
import Tabs from './containers/Tabs.vue';
|
|
29
29
|
import Cascader from './fields/Cascader.vue';
|
|
30
30
|
import Checkbox from './fields/Checkbox.vue';
|
|
@@ -46,6 +46,7 @@ import Text from './fields/Text.vue';
|
|
|
46
46
|
import Textarea from './fields/Textarea.vue';
|
|
47
47
|
import Time from './fields/Time.vue';
|
|
48
48
|
import Timerange from './fields/Timerange.vue';
|
|
49
|
+
import Table from './table/Table.vue';
|
|
49
50
|
import { setConfig } from './utils/config';
|
|
50
51
|
import Form from './Form.vue';
|
|
51
52
|
import FormDialog from './FormDialog.vue';
|
|
@@ -63,10 +64,11 @@ export { default as MFormDrawer } from './FormDrawer.vue';
|
|
|
63
64
|
export { default as MFormBox } from './FormBox.vue';
|
|
64
65
|
export { default as MContainer } from './containers/Container.vue';
|
|
65
66
|
export { default as MFieldset } from './containers/Fieldset.vue';
|
|
67
|
+
export { default as MFlexLayout } from './containers/FlexLayout.vue';
|
|
66
68
|
export { default as MPanel } from './containers/Panel.vue';
|
|
67
69
|
export { default as MRow } from './containers/Row.vue';
|
|
68
70
|
export { default as MTabs } from './containers/Tabs.vue';
|
|
69
|
-
export { default as MTable } from './
|
|
71
|
+
export { default as MTable } from './table/Table.vue';
|
|
70
72
|
export { default as MGroupList } from './containers/GroupList.vue';
|
|
71
73
|
export { default as MText } from './fields/Text.vue';
|
|
72
74
|
export { default as MNumber } from './fields/Number.vue';
|
|
@@ -114,6 +116,7 @@ export default {
|
|
|
114
116
|
app.component('m-form-step', MStep);
|
|
115
117
|
app.component('m-form-table', Table);
|
|
116
118
|
app.component('m-form-tab', Tabs);
|
|
119
|
+
app.component('m-form-flex-layout', FlexLayout);
|
|
117
120
|
app.component('m-fields-text', Text);
|
|
118
121
|
app.component('m-fields-img-upload', Text);
|
|
119
122
|
app.component('m-fields-number', Number);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<slot name="operateCol" :scope="{ $index: index, row: row }"></slot>
|
|
3
|
+
<TMagicButton
|
|
4
|
+
v-show="showDelete(index + 1 + currentPage * pageSize - 1)"
|
|
5
|
+
size="small"
|
|
6
|
+
type="danger"
|
|
7
|
+
link
|
|
8
|
+
title="删除"
|
|
9
|
+
:icon="Delete"
|
|
10
|
+
@click="removeHandler(index + 1 + currentPage * pageSize - 1)"
|
|
11
|
+
></TMagicButton>
|
|
12
|
+
|
|
13
|
+
<TMagicButton
|
|
14
|
+
v-if="copyable(index + 1 + currentPage * pageSize - 1)"
|
|
15
|
+
link
|
|
16
|
+
size="small"
|
|
17
|
+
type="primary"
|
|
18
|
+
title="复制"
|
|
19
|
+
:icon="DocumentCopy"
|
|
20
|
+
:disabled="disabled"
|
|
21
|
+
@click="copyHandler(index + 1 + currentPage * pageSize - 1)"
|
|
22
|
+
></TMagicButton>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup lang="ts">
|
|
26
|
+
import { inject } from 'vue';
|
|
27
|
+
import { Delete, DocumentCopy } from '@element-plus/icons-vue';
|
|
28
|
+
import { cloneDeep } from 'lodash-es';
|
|
29
|
+
|
|
30
|
+
import { TMagicButton } from '@tmagic/design';
|
|
31
|
+
|
|
32
|
+
import type { FormState, TableConfig } from '../schema';
|
|
33
|
+
|
|
34
|
+
const emit = defineEmits(['change']);
|
|
35
|
+
|
|
36
|
+
const props = defineProps<{
|
|
37
|
+
config: TableConfig;
|
|
38
|
+
model: any;
|
|
39
|
+
name: string | number;
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
currentPage: number;
|
|
42
|
+
pageSize: number;
|
|
43
|
+
index: number;
|
|
44
|
+
row: any;
|
|
45
|
+
prop?: string;
|
|
46
|
+
sortKey?: string;
|
|
47
|
+
}>();
|
|
48
|
+
|
|
49
|
+
const mForm = inject<FormState | undefined>('mForm');
|
|
50
|
+
|
|
51
|
+
const removeHandler = (index: number) => {
|
|
52
|
+
if (props.disabled) return;
|
|
53
|
+
emit('change', props.model[props.name].toSpliced(index, 1));
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const copyHandler = (index: number) => {
|
|
57
|
+
const inputs = cloneDeep(props.model[props.name][index]);
|
|
58
|
+
const { length } = props.model[props.name];
|
|
59
|
+
if (props.sortKey && length) {
|
|
60
|
+
inputs[props.sortKey] = props.model[props.name][length - 1][props.sortKey] - 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
emit('change', [...props.model[props.name], inputs], {
|
|
64
|
+
changeRecords: [
|
|
65
|
+
{
|
|
66
|
+
propPath: `${props.prop}.${props.model[props.name].length}`,
|
|
67
|
+
value: inputs,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// 希望支持单行可控制是否显示删除按钮,不会影响现有逻辑
|
|
74
|
+
const showDelete = (index: number) => {
|
|
75
|
+
const deleteFunc = props.config.delete;
|
|
76
|
+
if (deleteFunc && typeof deleteFunc === 'function') {
|
|
77
|
+
return deleteFunc(props.model[props.name], index, mForm?.values);
|
|
78
|
+
}
|
|
79
|
+
return props.config.delete ?? true;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const copyable = (index: number) => {
|
|
83
|
+
const copyableFunc = props.config.copyable;
|
|
84
|
+
if (copyableFunc && typeof copyableFunc === 'function') {
|
|
85
|
+
return copyableFunc(mForm, {
|
|
86
|
+
values: mForm?.initValues || {},
|
|
87
|
+
model: props.model,
|
|
88
|
+
parent: mForm?.parentValues || {},
|
|
89
|
+
formValue: mForm?.values || props.model,
|
|
90
|
+
prop: props.prop,
|
|
91
|
+
config: props.config,
|
|
92
|
+
index,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return props.config.copyable ?? true;
|
|
96
|
+
};
|
|
97
|
+
</script>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<TMagicTooltip v-if="index + 1 + currentPage * pageSize - 1 !== 0" content="点击上移,双击置顶" placement="top">
|
|
3
|
+
<TMagicButton
|
|
4
|
+
plain
|
|
5
|
+
size="small"
|
|
6
|
+
type="primary"
|
|
7
|
+
:icon="ArrowUp"
|
|
8
|
+
:disabled="disabled"
|
|
9
|
+
link
|
|
10
|
+
@click="upHandler(index + 1 + currentPage * pageSize - 1)"
|
|
11
|
+
@dblclick="topHandler(index + 1 + currentPage * pageSize - 1)"
|
|
12
|
+
></TMagicButton>
|
|
13
|
+
</TMagicTooltip>
|
|
14
|
+
<TMagicTooltip
|
|
15
|
+
v-if="index + 1 + currentPage * pageSize - 1 !== model[name].length - 1"
|
|
16
|
+
content="点击下移,双击置底"
|
|
17
|
+
placement="top"
|
|
18
|
+
>
|
|
19
|
+
<TMagicButton
|
|
20
|
+
plain
|
|
21
|
+
size="small"
|
|
22
|
+
type="primary"
|
|
23
|
+
:icon="ArrowDown"
|
|
24
|
+
:disabled="disabled"
|
|
25
|
+
link
|
|
26
|
+
@click="downHandler(index + 1 + currentPage * pageSize - 1)"
|
|
27
|
+
@dblclick="bottomHandler(index + 1 + currentPage * pageSize - 1)"
|
|
28
|
+
></TMagicButton>
|
|
29
|
+
</TMagicTooltip>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script setup lang="ts">
|
|
33
|
+
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue';
|
|
34
|
+
|
|
35
|
+
import { TMagicButton, TMagicTooltip } from '@tmagic/design';
|
|
36
|
+
|
|
37
|
+
const props = defineProps<{
|
|
38
|
+
index: number;
|
|
39
|
+
disabled?: boolean;
|
|
40
|
+
currentPage: number;
|
|
41
|
+
pageSize: number;
|
|
42
|
+
name: string | number;
|
|
43
|
+
model: any;
|
|
44
|
+
}>();
|
|
45
|
+
|
|
46
|
+
const emit = defineEmits(['swap']);
|
|
47
|
+
|
|
48
|
+
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
49
|
+
|
|
50
|
+
const upHandler = (index: number) => {
|
|
51
|
+
if (timer) {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
timer = setTimeout(() => {
|
|
56
|
+
emit('swap', index, index - 1);
|
|
57
|
+
timer = null;
|
|
58
|
+
}, 300);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const topHandler = (index: number) => {
|
|
62
|
+
if (timer) {
|
|
63
|
+
clearTimeout(timer);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 首先判断当前元素需要上移几个位置,置底移动到数组的第一位
|
|
67
|
+
const moveNum = index;
|
|
68
|
+
|
|
69
|
+
// 循环出需要一个一个上移的次数
|
|
70
|
+
for (let i = 0; i < moveNum; i++) {
|
|
71
|
+
emit('swap', index, index - 1);
|
|
72
|
+
index -= 1;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const downHandler = (index: number) => {
|
|
77
|
+
if (timer) {
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
timer = setTimeout(() => {
|
|
82
|
+
emit('swap', index, index + 1);
|
|
83
|
+
timer = null;
|
|
84
|
+
}, 300);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const bottomHandler = (index: number) => {
|
|
88
|
+
if (timer) {
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 首先判断当前元素需要上移几个位置,置底移动到数组的第一位
|
|
93
|
+
const moveNum = props.model[props.name].length - 1 - index;
|
|
94
|
+
|
|
95
|
+
// 循环出需要一个一个上移的次数
|
|
96
|
+
for (let i = 0; i < moveNum; i++) {
|
|
97
|
+
emit('swap', index, index + 1);
|
|
98
|
+
index += 1;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
</script>
|