vue-2024-ui 0.0.7 → 0.0.8
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/README.form.md +2 -2
- package/package.json +1 -1
- package/src/components/g-form.vue +56 -85
- package/src/components/g-table.vue +95 -67
- package/src/components/index.d.ts +27 -12
- package/src/components/index.js +92 -15
package/README.form.md
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
| --------- | ------------------------------------------------------------------- | ------ | -------------------------------------------------------------------------------------------- |
|
|
11
11
|
| columns | 表单列数 | number | 2 |
|
|
12
12
|
| footer | 控制表单底部按钮是否显示和样式设置,hidden默认是false,style控制样式 | object | ```{hidden: false, style:{ display:"flex","align-items":"center",justifyContent:"center"}``` |
|
|
13
|
-
| submit | 表单提交按钮,增加了
|
|
14
|
-
| reset | 表单重置按钮,增加了
|
|
13
|
+
| submit | 表单提交按钮,增加了label,hidden 属性和click方法 | object | ``` {type: "primary",label: "提交",hidden: false,click: async (model) => {...}, } ``` |
|
|
14
|
+
| reset | 表单重置按钮,增加了label,hidden 属性和click方法 | object | ``` {type: "primary",label: "重置",hidden: false,click: () => {...}, } ``` |
|
|
15
15
|
| formItems | 通过style属性设置所有items的样式 | object | ``` style:{width:100%} ``` |
|
|
16
16
|
|
|
17
17
|
## form 增加的事件
|
package/package.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
<el-form ref="gform" :model="model" v-bind="model.form" class="g-form-container">
|
|
3
3
|
<slot>
|
|
4
4
|
<el-form-item :label="item.label" :prop="`${key}.value`" :rules="getItemRulesByItem(item)"
|
|
5
|
-
v-for="(item, key) of items" :key="key" v-bind="{ ...model
|
|
6
|
-
:style="{ ...model
|
|
5
|
+
v-for="(item, key) of items" :key="key" v-bind="{ ...model?.formItems, ...item?.formItem }"
|
|
6
|
+
:style="{ ...model?.formItems?.style, ...item?.formItem?.style }">
|
|
7
7
|
<slot :name="key" :item :model>
|
|
8
8
|
<g-ctrl v-model="model[key].value" :item :ctrlKey="key" :model class="g-ctrl-container">
|
|
9
9
|
<template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
|
|
@@ -15,29 +15,28 @@
|
|
|
15
15
|
<slot :name="`${key}-label`" :data :item :model>{{ item.label }}</slot>
|
|
16
16
|
</template>
|
|
17
17
|
</el-form-item>
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
</slot>
|
|
33
|
-
</el-form-item>
|
|
18
|
+
<slot name="footer" v-if="!model.form.footer.hidden">
|
|
19
|
+
<div :style="model.form.footer.style">
|
|
20
|
+
<slot name="footer-left"></slot>
|
|
21
|
+
<el-button @click="model.form.submit.click(model)" v-bind="model.form.submit"
|
|
22
|
+
v-if="!model?.form?.submit?.hidden">
|
|
23
|
+
{{ model?.form?.submit?.label }}
|
|
24
|
+
</el-button>
|
|
25
|
+
<el-button @click="model.form.reset.click(model)" v-bind="model.form.reset"
|
|
26
|
+
v-if="!model?.form?.reset?.hidden">{{
|
|
27
|
+
model?.form?.reset?.label
|
|
28
|
+
}}</el-button>
|
|
29
|
+
<slot name="footer-right"></slot>
|
|
30
|
+
</div>
|
|
31
|
+
</slot>
|
|
34
32
|
</slot>
|
|
35
33
|
</el-form>
|
|
36
34
|
</template>
|
|
37
35
|
|
|
38
36
|
<script setup>
|
|
39
|
-
import { computed, inject, onMounted, ref, useAttrs, watch } from "vue";
|
|
37
|
+
import { computed, inject, onMounted, ref, useAttrs, watch, watchEffect } from "vue";
|
|
40
38
|
import gCtrl from "./g-ctrl.vue";
|
|
39
|
+
import { convertToPx, mergeObjects } from "./index";
|
|
41
40
|
defineOptions({
|
|
42
41
|
name: "g-form",
|
|
43
42
|
inheritAttrs: false
|
|
@@ -45,11 +44,10 @@ defineOptions({
|
|
|
45
44
|
const model = defineModel({ required: true });
|
|
46
45
|
const emits = defineEmits(["submit", "reset"]);
|
|
47
46
|
const gform = ref(null);
|
|
48
|
-
const columnsWidth = ref(0);
|
|
49
47
|
let marginRight = ref(32);
|
|
50
|
-
const options=inject('options');
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
const options = inject('options');
|
|
49
|
+
|
|
50
|
+
const defaultFormAttrs = {
|
|
53
51
|
inline: true,
|
|
54
52
|
type: "hidden",
|
|
55
53
|
"scroll-to-error": true,
|
|
@@ -57,40 +55,25 @@ model.value.form = {
|
|
|
57
55
|
"status-icon": true,
|
|
58
56
|
"scroll-into-view-options": true,
|
|
59
57
|
columns: 2,
|
|
60
|
-
...options?.form,
|
|
61
|
-
...model.value.form,
|
|
62
58
|
style: {
|
|
63
59
|
width: "600px",
|
|
64
|
-
|
|
65
|
-
borderRadius: "10px",
|
|
66
|
-
padding: "0px",
|
|
67
|
-
paddingTop: "20px",
|
|
68
|
-
margin: "0px",
|
|
69
|
-
boxShadow: "0 0 5px rgba(0, 0, 0, 0.1)",
|
|
70
|
-
...options?.form?.style,
|
|
71
|
-
...model.value.form?.style,
|
|
72
|
-
...useAttrs().style
|
|
60
|
+
...useAttrs()?.style
|
|
73
61
|
},
|
|
74
62
|
// 表单底部属性
|
|
75
63
|
footer: {
|
|
76
64
|
hidden: false,
|
|
77
|
-
...options?.form?.footer,
|
|
78
|
-
...model.value.form?.footer,
|
|
79
65
|
style: {
|
|
80
|
-
display: "flex", width: "100%", "align-items": "center", justifyContent: "center", margin: "5px",
|
|
81
|
-
...options?.form?.footer?.style,
|
|
82
|
-
...model.value.form?.footer?.style
|
|
66
|
+
display: "flex", width: "100%", "align-items": "center", justifyContent: "center", margin: "5px",
|
|
83
67
|
},
|
|
84
68
|
},
|
|
85
69
|
//表单提交按钮属性
|
|
86
70
|
submit: {
|
|
87
71
|
type: "primary",
|
|
88
72
|
disabled: false,
|
|
89
|
-
|
|
73
|
+
label: "提交",
|
|
90
74
|
plain: true,
|
|
91
75
|
hidden: false,
|
|
92
|
-
|
|
93
|
-
submit: async (model) => {
|
|
76
|
+
click: async (model) => {
|
|
94
77
|
if (!gform.value) return
|
|
95
78
|
await gform.value.validate((valid, fields) => {
|
|
96
79
|
if (valid) {
|
|
@@ -100,15 +83,14 @@ model.value.form = {
|
|
|
100
83
|
}
|
|
101
84
|
})
|
|
102
85
|
},
|
|
103
|
-
...model.value.form?.submit
|
|
104
86
|
},
|
|
105
87
|
//表单重置按钮属性
|
|
106
88
|
reset: {
|
|
107
89
|
disabled: false,
|
|
108
|
-
|
|
90
|
+
label: "重置",
|
|
109
91
|
hidden: false,
|
|
110
92
|
plain: true,
|
|
111
|
-
|
|
93
|
+
click: () => {
|
|
112
94
|
if (!gform.value) return
|
|
113
95
|
let isreset = true;
|
|
114
96
|
emits("reset", (flag) => {
|
|
@@ -118,25 +100,24 @@ model.value.form = {
|
|
|
118
100
|
gform.value.resetFields();
|
|
119
101
|
}
|
|
120
102
|
},
|
|
121
|
-
...options?.form?.reset,
|
|
122
|
-
...model.value.form?.reset
|
|
123
103
|
},
|
|
124
|
-
dialog: {
|
|
125
|
-
width: 635,
|
|
126
|
-
...options?.form?.dialog,
|
|
127
|
-
...model.value.form?.dialog
|
|
128
|
-
}
|
|
129
104
|
};
|
|
130
|
-
|
|
131
|
-
|
|
105
|
+
model.value.form = mergeObjects(
|
|
106
|
+
defaultFormAttrs,
|
|
107
|
+
options?.form,
|
|
108
|
+
model.value?.form
|
|
109
|
+
);
|
|
110
|
+
const defaultFormItemsAttrs = {
|
|
132
111
|
type: "hidden",
|
|
133
112
|
style: {
|
|
134
113
|
width: "100%",
|
|
135
|
-
|
|
136
|
-
...model.value.formItems?.style
|
|
137
|
-
},
|
|
138
|
-
...model.value.formItems,
|
|
114
|
+
}
|
|
139
115
|
};
|
|
116
|
+
model.value.formItems = mergeObjects(
|
|
117
|
+
defaultFormItemsAttrs,
|
|
118
|
+
options?.formItems,
|
|
119
|
+
model?.formItems
|
|
120
|
+
);
|
|
140
121
|
|
|
141
122
|
//获取表单项验证规则
|
|
142
123
|
const getItemRulesByItem = (item) => {
|
|
@@ -223,48 +204,38 @@ const getItemRulesByItem = (item) => {
|
|
|
223
204
|
return itemRules;
|
|
224
205
|
}
|
|
225
206
|
|
|
226
|
-
onMounted(() => {
|
|
227
|
-
load();
|
|
228
|
-
})
|
|
207
|
+
onMounted(() => { load(); })
|
|
229
208
|
|
|
230
209
|
const load = () => {
|
|
231
210
|
if (!model.value.form.inline) {
|
|
232
211
|
model.value.form.columns = 1;
|
|
233
212
|
}
|
|
234
|
-
if (model.value.form.style.width) {
|
|
235
|
-
columnsWidth.value = removePx(model.value.form.style.width) / model.value.form.columns;
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
model.value.form.style.width = "600px";
|
|
239
|
-
}
|
|
240
|
-
model.value.form.dialog.width = +model.value?.form?.style?.width.replace("px", "") + 35 + "px";
|
|
241
213
|
for (const [key, value] of Object.entries(items.value)) {
|
|
242
|
-
model.value[key].formItem = { ...model.value[key].formItem, ...value.formItem }
|
|
214
|
+
model.value[key].formItem = { ...model.value[key].formItem, ...value.formItem };
|
|
243
215
|
model.value[key].formItem.style = { ...model.value[key].formItem.style, ...value.formItem.style };
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
model.value[key].formItem.style.width = `calc(${columnsWidth.value - marginRight.value}px)`;
|
|
250
|
-
}
|
|
251
|
-
} else {
|
|
252
|
-
model.value[key].formItem.style.width = `calc(${columnsWidth.value - marginRight.value}px)`;
|
|
253
|
-
}
|
|
216
|
+
|
|
217
|
+
const columnWidth = value.columns && value.columns > 1 ?
|
|
218
|
+
columnsWidth.value * value.columns - (value.columns - 1) * marginRight.value :
|
|
219
|
+
columnsWidth.value - marginRight.value;
|
|
220
|
+
model.value[key].formItem.style.width = `calc(${columnWidth}px)`;
|
|
254
221
|
}
|
|
255
|
-
}
|
|
222
|
+
};
|
|
256
223
|
|
|
257
224
|
watch(() => model.value.form.columns, () => load());
|
|
258
225
|
watch(() => model.value.form.inline, () => load());
|
|
259
226
|
|
|
260
|
-
const
|
|
227
|
+
const columnsWidth = computed(() => convertToPx(model.value.form.style.width) / model.value.form.columns);
|
|
228
|
+
console.log(columnsWidth.value);
|
|
261
229
|
//表单项
|
|
262
|
-
const items = computed(() => Object.fromEntries(Object.entries(model.value)
|
|
230
|
+
const items = computed(() => Object.fromEntries(Object.entries(model.value)
|
|
231
|
+
.filter(a => a[1].type != "hidden")
|
|
263
232
|
.filter(a => (a[1].edit !== false))
|
|
264
233
|
.filter(a => (a[1].type !== "control"))
|
|
265
234
|
.map(key => [key[0], key[1]])));
|
|
266
235
|
//表单提交对象
|
|
267
|
-
const formInfo = computed(() => Object.fromEntries(Object.entries(model.value)
|
|
268
|
-
|
|
269
|
-
|
|
236
|
+
const formInfo = computed(() => Object.fromEntries(Object.entries(model.value)
|
|
237
|
+
.filter(a => a[1].type != "hidden")
|
|
238
|
+
.filter(a => a[1].type != "control")
|
|
239
|
+
.map(key => [key[0], key[1].value])));
|
|
240
|
+
|
|
270
241
|
</script>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<slot name="control-view" :row :column :$index
|
|
17
17
|
v-if="model.control.view.auth(row, column, $index)">
|
|
18
18
|
<el-button v-bind="model.control.view"
|
|
19
|
-
@click="model.control.view.
|
|
19
|
+
@click="model.control.view.click(row, column, $index, model)">{{
|
|
20
20
|
model.control.view.label
|
|
21
21
|
}}</el-button>
|
|
22
22
|
</slot>
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<slot name="control-edit" :row :column :$index
|
|
25
25
|
v-if="model.control.edit.auth(row, column, $index)">
|
|
26
26
|
<el-button v-bind="model.control.edit"
|
|
27
|
-
@click="model.control.edit.
|
|
27
|
+
@click="model.control.edit.click(row, column, $index, model)">{{
|
|
28
28
|
model.control.edit.label
|
|
29
29
|
}}</el-button>
|
|
30
30
|
</slot>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
<slot name="control-delete" :row :column :$index
|
|
33
33
|
v-if="model.control.delete.auth(row, column, $index)">
|
|
34
34
|
<el-button v-bind="model.control.delete"
|
|
35
|
-
@click="model.control.delete.
|
|
35
|
+
@click="model.control.delete.click(row, column, $index)">{{
|
|
36
36
|
model.control.delete.label }}</el-button>
|
|
37
37
|
</slot>
|
|
38
38
|
<slot name="control-right" :row :column :$index> </slot>
|
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
<script setup>
|
|
66
66
|
import dayjs from 'dayjs';
|
|
67
67
|
import { ElMessageBox } from 'element-plus';
|
|
68
|
-
import { computed, onMounted,
|
|
68
|
+
import { computed, onMounted, ref, watchEffect, h, inject } from 'vue';
|
|
69
69
|
import GForm from './g-form.vue';
|
|
70
|
-
import { openModal } from './index';
|
|
70
|
+
import { openModal, mergeObjects,convertToPx } from './index';
|
|
71
71
|
|
|
72
72
|
defineOptions({
|
|
73
73
|
name: "g-table",
|
|
@@ -79,7 +79,7 @@ const model = defineModel({ required: true });
|
|
|
79
79
|
const options = inject('options');
|
|
80
80
|
|
|
81
81
|
//table default attrs
|
|
82
|
-
|
|
82
|
+
const defaultTableAttrs = {
|
|
83
83
|
data: [],
|
|
84
84
|
border: true,
|
|
85
85
|
stripe: true,
|
|
@@ -87,8 +87,6 @@ model.value.table = {
|
|
|
87
87
|
fit: false,
|
|
88
88
|
type: "hidden",
|
|
89
89
|
height: "calc(100vh - 55px)",
|
|
90
|
-
...options?.table,
|
|
91
|
-
...model.value.table,
|
|
92
90
|
load: () => {
|
|
93
91
|
let { currentPage, pageSize } = model.value.table.page;
|
|
94
92
|
emits('load', { currentPage, pageSize }, (data, total) => {
|
|
@@ -97,112 +95,139 @@ model.value.table = {
|
|
|
97
95
|
});
|
|
98
96
|
},
|
|
99
97
|
page: {
|
|
100
|
-
background:
|
|
98
|
+
background: "red",
|
|
101
99
|
total: 0,
|
|
102
100
|
pageSize: 20,
|
|
103
101
|
currentPage: 1,
|
|
104
102
|
pageSizes: [5, 10, 20, 30, 40, 50],
|
|
105
103
|
layout: 'total, sizes, prev, pager, next, jumper',
|
|
106
|
-
...options?.table?.page,
|
|
107
|
-
...model.value.table?.page,
|
|
108
104
|
style: {
|
|
109
105
|
display: 'flex',
|
|
110
106
|
justifyContent: 'flex-end',
|
|
111
107
|
padding: "10px",
|
|
112
|
-
...model.value.table?.page?.style
|
|
113
108
|
},
|
|
114
109
|
}
|
|
115
|
-
}
|
|
110
|
+
};
|
|
111
|
+
model.value.table = mergeObjects(
|
|
112
|
+
defaultTableAttrs,
|
|
113
|
+
options?.table,
|
|
114
|
+
model.value.table
|
|
115
|
+
);
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
type: '
|
|
119
|
-
...options?.form,
|
|
120
|
-
...model.value.form,
|
|
121
|
-
dialog: {
|
|
122
|
-
width: 635,
|
|
123
|
-
...model.value.form?.dialog,
|
|
124
|
-
style: {
|
|
125
|
-
...model.value.form?.dialog?.style
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
model.value.control = {
|
|
130
|
-
type: 'control', label: '操作', edit: false, width: 250, fixed: 'right',...options?.control, ...model.value?.control,
|
|
117
|
+
const defaultControl = {
|
|
118
|
+
type: 'control', label: '操作', edit: false, width: 250, fixed: 'right',
|
|
131
119
|
style: { ...model.value?.control?.style },
|
|
120
|
+
add: {
|
|
121
|
+
label: '新增', text: false, type: 'primary',
|
|
122
|
+
dialog: {
|
|
123
|
+
title: '新增',
|
|
124
|
+
popMode: "dialog",
|
|
125
|
+
slots: {
|
|
126
|
+
default: () => h(GForm, { modelValue: model.value }),
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
auth: () => {
|
|
130
|
+
return true;
|
|
131
|
+
},
|
|
132
|
+
click: (row, column, $index, m) => {
|
|
133
|
+
model.value.form.disabled = undefined;
|
|
134
|
+
emits("add", row, column, $index, m);
|
|
135
|
+
Object.keys(row).forEach(key => {
|
|
136
|
+
if (model.value[key]) {
|
|
137
|
+
model.value[key].value = row[key];
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
openModal(model.value.control.add.dialog, model.value?.control?.add?.dialog?.popMode);
|
|
141
|
+
},
|
|
142
|
+
},
|
|
132
143
|
view: {
|
|
133
144
|
label: '查看', text: true, type: 'success',
|
|
145
|
+
dialog: {
|
|
146
|
+
title: '查看',
|
|
147
|
+
popMode: "dialog",
|
|
148
|
+
slots: {
|
|
149
|
+
default: () => h(GForm, { modelValue: model.value }),
|
|
150
|
+
},
|
|
151
|
+
},
|
|
134
152
|
auth: (row, column, $index) => {
|
|
135
153
|
return false;
|
|
136
154
|
},
|
|
137
|
-
|
|
155
|
+
click: (row, column, $index, m) => {
|
|
156
|
+
let w = model.value?.form?.style?.width || 600;
|
|
157
|
+
if (model.value.control.view.dialog.popMode == "drawer") {
|
|
158
|
+
model.value.control.view.dialog.size = convertToPx(w) + 45;
|
|
159
|
+
} else {
|
|
160
|
+
model.value.control.view.dialog.width = convertToPx(w) + 35;
|
|
161
|
+
}
|
|
138
162
|
model.value.form.disabled = true;
|
|
139
163
|
emits("view", row, column, $index, m);
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
...model.value.form.dialog,
|
|
145
|
-
slots: {
|
|
146
|
-
// 自定义插槽内容
|
|
147
|
-
default: () => h(GForm, { modelValue: model.value }),
|
|
148
|
-
...model.value?.form?.dialog?.slots
|
|
149
|
-
},
|
|
164
|
+
Object.keys(row).forEach(key => {
|
|
165
|
+
if (model.value[key]) {
|
|
166
|
+
model.value[key].value = row[key];
|
|
167
|
+
}
|
|
150
168
|
});
|
|
169
|
+
openModal(model.value.control.view.dialog, model.value?.control?.view?.dialog?.popMode);
|
|
151
170
|
},
|
|
152
|
-
...options?.control?.view,
|
|
153
|
-
...model.value?.control?.view
|
|
154
171
|
},
|
|
155
172
|
edit: {
|
|
156
173
|
label: '编辑', text: true, type: 'primary',
|
|
174
|
+
dialog: {
|
|
175
|
+
title: '编辑',
|
|
176
|
+
popMode: "dialog",
|
|
177
|
+
slots: {
|
|
178
|
+
default: () => h(GForm, { modelValue: model.value }),
|
|
179
|
+
},
|
|
180
|
+
},
|
|
157
181
|
auth: (row, column, $index) => {
|
|
158
182
|
return true;
|
|
159
183
|
},
|
|
160
|
-
|
|
184
|
+
click: (row, column, $index, m) => {
|
|
161
185
|
model.value.form.disabled = undefined;
|
|
186
|
+
let w = model.value?.form?.style?.width || 600;
|
|
187
|
+
if (model.value.control.edit.dialog.popMode == "drawer") {
|
|
188
|
+
model.value.control.edit.dialog.size = convertToPx(w) + 45;
|
|
189
|
+
} else {
|
|
190
|
+
model.value.control.edit.dialog.width = convertToPx(w) + 35;
|
|
191
|
+
}
|
|
162
192
|
emits("edit", row, column, $index, m);
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
...model.value.form.dialog,
|
|
168
|
-
slots: {
|
|
169
|
-
// 自定义插槽内容
|
|
170
|
-
default: () => h(GForm, { modelValue: model.value }),
|
|
171
|
-
...model.value?.form?.dialog?.slots
|
|
172
|
-
},
|
|
193
|
+
Object.keys(row).forEach(key => {
|
|
194
|
+
if (model.value[key]) {
|
|
195
|
+
model.value[key].value = row[key];
|
|
196
|
+
}
|
|
173
197
|
});
|
|
174
|
-
|
|
175
|
-
},
|
|
176
|
-
...options?.control?.edit,
|
|
177
|
-
...model.value?.control?.edit
|
|
198
|
+
openModal(model.value?.control?.edit?.dialog, model.value?.control?.edit?.dialog?.popMode);
|
|
199
|
+
},
|
|
178
200
|
},
|
|
179
201
|
delete: {
|
|
180
202
|
text: true, label: '删除', type: 'danger',
|
|
181
203
|
auth: (row, column, $index) => {
|
|
182
204
|
return true;
|
|
183
205
|
},
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
206
|
+
dialog: {
|
|
207
|
+
message: '此操作将永久删除该文件, 是否继续?', title: '提示', options: { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }
|
|
208
|
+
},
|
|
209
|
+
click: (row, column, $index) => {
|
|
210
|
+
let { message, title, options } = model.value.control.delete.dialog;
|
|
211
|
+
ElMessageBox.confirm(message, title, options).then(() => {
|
|
190
212
|
emits("delete", { row, column, $index }, (res) => {
|
|
191
213
|
if (res) {
|
|
192
214
|
model.value.table.data.splice($index, 1);
|
|
193
|
-
console.log(model.value.table.data)
|
|
194
215
|
}
|
|
195
216
|
})
|
|
196
217
|
}).catch(() => { });
|
|
197
218
|
|
|
198
|
-
},
|
|
199
|
-
...options?.control?.delete,
|
|
200
|
-
...model.value?.control?.delete
|
|
219
|
+
},
|
|
201
220
|
},
|
|
202
221
|
};
|
|
203
222
|
|
|
223
|
+
model.value.control = mergeObjects(
|
|
224
|
+
defaultControl,
|
|
225
|
+
options?.control,
|
|
226
|
+
model.value?.control
|
|
227
|
+
);
|
|
228
|
+
|
|
204
229
|
//table column default attrs
|
|
205
|
-
const itemValue =
|
|
230
|
+
const itemValue = ref({
|
|
206
231
|
width: 100, align: "center", formatter: (row, column, cellValue, index) => {
|
|
207
232
|
return cellValue;
|
|
208
233
|
}
|
|
@@ -260,7 +285,10 @@ const tableColumns = computed(() => Object.fromEntries(
|
|
|
260
285
|
Object.entries(model.value)
|
|
261
286
|
.filter(a => a[1].type != "hidden")
|
|
262
287
|
.filter(a => a[1].visible !== false)
|
|
263
|
-
.map(key =>
|
|
288
|
+
.map(key => {
|
|
289
|
+
key[1].sort = key[1].sort || 0;
|
|
290
|
+
return [key[0], key[1]]
|
|
291
|
+
}).sort((a, b) => a[1].sort - b[1].sort))
|
|
264
292
|
);
|
|
265
293
|
</script>
|
|
266
294
|
|
|
@@ -1,19 +1,34 @@
|
|
|
1
1
|
import { App } from 'vue';
|
|
2
|
+
import { Component } from 'vue';
|
|
3
|
+
import { ElDialogProps, ElDrawerProps } from 'element-plus';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
declare module 'vue' {
|
|
6
|
+
interface ComponentCustomProperties {
|
|
7
|
+
openModel: typeof openModal;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface GlobalOptions {
|
|
12
|
+
// 在这里定义全局选项的类型
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface OpenModalProps {
|
|
16
|
+
slots?: {
|
|
17
|
+
default?: () => any;
|
|
18
|
+
header?: () => any;
|
|
19
|
+
footer?: () => any;
|
|
9
20
|
};
|
|
10
|
-
|
|
21
|
+
// 在这里定义其他传递给openModal函数的属性
|
|
11
22
|
}
|
|
12
23
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
24
|
+
export function install(app: App, options?: GlobalOptions): void;
|
|
25
|
+
export function openModal(props?: OpenModalProps, popMode?: 'dialog' | 'drawer'): void;
|
|
26
|
+
export function convertToPx(value: string | number, referenceSize?: number): number;
|
|
27
|
+
export function mergeObjects<T extends object>(...objects: T[]): T;
|
|
16
28
|
|
|
17
|
-
|
|
29
|
+
declare const components: {
|
|
30
|
+
gTable: Component;
|
|
31
|
+
gForm: Component;
|
|
32
|
+
};
|
|
18
33
|
|
|
19
|
-
export
|
|
34
|
+
export default components;
|
package/src/components/index.js
CHANGED
|
@@ -4,18 +4,25 @@ import ElementPlus from 'element-plus'
|
|
|
4
4
|
import { ElDialog, ElDrawer } from "element-plus";
|
|
5
5
|
import gTable from "./g-table.vue";
|
|
6
6
|
import gForm from "./g-form.vue";
|
|
7
|
-
import { createApp, h, provide,
|
|
8
|
-
const
|
|
7
|
+
import { createApp, h, provide, readonly, ref } from "vue";
|
|
8
|
+
const globalOptions = {};
|
|
9
|
+
|
|
10
|
+
const components = [
|
|
11
|
+
gTable,
|
|
12
|
+
gForm
|
|
13
|
+
]
|
|
9
14
|
|
|
10
15
|
export default {
|
|
11
16
|
install(app, options = {}) {
|
|
12
|
-
Object.assign(
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
Object.assign(globalOptions, options);
|
|
18
|
+
for (const component of components) {
|
|
19
|
+
app.component(component.name, component);
|
|
20
|
+
}
|
|
15
21
|
app.provide("options", readonly(options));
|
|
22
|
+
app.config.globalProperties.openModel = openModal;
|
|
16
23
|
}
|
|
17
24
|
}
|
|
18
|
-
const openModal = (props = {},
|
|
25
|
+
const openModal = (props = {}, popMode = "dialog") => {
|
|
19
26
|
const el = document.createElement('div');
|
|
20
27
|
const app = createApp({
|
|
21
28
|
setup() {
|
|
@@ -25,25 +32,95 @@ const openModal = (props = {}, comType = "dialog") => {
|
|
|
25
32
|
app.unmount(); // 关闭对话框时卸载组件
|
|
26
33
|
delete el.remove(); // 关闭对话框时删除元素
|
|
27
34
|
};
|
|
28
|
-
provide("options",
|
|
29
|
-
return () => h(
|
|
35
|
+
provide("options", globalOptions);
|
|
36
|
+
return () => h(popMode == "dialog" ? ElDialog : popMode == "drawer" ? ElDrawer : null, {
|
|
30
37
|
modelValue: visible.value,
|
|
31
38
|
'onUpdate:modelValue': closeModal,
|
|
32
39
|
draggable: true,
|
|
33
40
|
"append-to-body": true,
|
|
34
|
-
"v-if": visible.value,
|
|
35
41
|
...props
|
|
36
42
|
},
|
|
37
|
-
|
|
38
|
-
props.slots
|
|
39
|
-
props.slots
|
|
40
|
-
props.slots
|
|
41
|
-
|
|
43
|
+
{
|
|
44
|
+
default: props.slots?.default ? () => h('div', {}, props.slots.default()) : null,
|
|
45
|
+
header: props.slots?.header ? () => h('div', {}, props.slots.header()) : null,
|
|
46
|
+
footer: props.slots?.footer ? () => h('div', {}, props.slots.footer()) : null
|
|
47
|
+
}
|
|
42
48
|
);
|
|
43
49
|
}
|
|
44
50
|
});
|
|
51
|
+
for (const component of components) {
|
|
52
|
+
app.component(component.name, component);
|
|
53
|
+
}
|
|
45
54
|
app.use(ElementPlus).mount(el);
|
|
46
55
|
document.body.appendChild(el);
|
|
47
56
|
};
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
function convertToPx(value, referenceSize = window.innerWidth) {
|
|
59
|
+
// 如果已经是px,直接返回
|
|
60
|
+
if (typeof value === 'number') {
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
if (value.endsWith('px')) {
|
|
64
|
+
return parseFloat(value);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 处理vh和vw
|
|
68
|
+
const viewportHeight = window.innerHeight;
|
|
69
|
+
const viewportWidth = window.innerWidth;
|
|
70
|
+
if (value.endsWith('vh')) {
|
|
71
|
+
return (viewportHeight * parseFloat(value) / 100);
|
|
72
|
+
}
|
|
73
|
+
if (value.endsWith('vw')) {
|
|
74
|
+
return (viewportWidth * parseFloat(value) / 100);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 处理%值,需要提供参考大小
|
|
78
|
+
if (value.endsWith('%')) {
|
|
79
|
+
if (typeof referenceSize !== 'number') {
|
|
80
|
+
throw new Error('Reference size is required to convert % to px');
|
|
81
|
+
}
|
|
82
|
+
return (referenceSize * parseFloat(value) / 100);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 处理calc表达式
|
|
86
|
+
if (value.startsWith('calc(') && value.endsWith(')')) {
|
|
87
|
+
const calcExpr = value.slice(5, -1).trim();
|
|
88
|
+
// 使用一个安全的eval替代方案来解析calc表达式
|
|
89
|
+
function safeEval(expr) {
|
|
90
|
+
// 只允许数字、加减乘除运算符、小括号和空格
|
|
91
|
+
if (/[0-9+\-*/().\s]+$/.test(expr)) {
|
|
92
|
+
return new Function('return ' + expr)();
|
|
93
|
+
} else {
|
|
94
|
+
throw new Error('Invalid calc expression');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// 在这里,我们假设calc表达式中可能包含其他单位,因此递归调用parseValueToPx
|
|
98
|
+
const result = safeEval(calcExpr.replace(/([0-9.]+)([a-z%]+)/g, (match, number, unit) => {
|
|
99
|
+
return convertToPx(number + unit, referenceSize);
|
|
100
|
+
}));
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 如果无法识别单位,抛出错误
|
|
105
|
+
throw new Error('Unsupported unit in value: ' + value);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
function mergeObjects(...objects) {
|
|
110
|
+
const result = ref({});
|
|
111
|
+
for (const obj of objects) {
|
|
112
|
+
if (obj && typeof obj === 'object') {
|
|
113
|
+
for (const key in obj) {
|
|
114
|
+
if (obj.hasOwnProperty(key)) {
|
|
115
|
+
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
|
|
116
|
+
result.value[key] = mergeObjects(result.value[key], obj[key]);
|
|
117
|
+
} else {
|
|
118
|
+
result.value[key] = obj[key];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return result.value;
|
|
125
|
+
}
|
|
126
|
+
export { openModal, convertToPx, mergeObjects };
|