vue-2024-ui 0.0.10 → 0.0.11
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/package.json +2 -1
- package/src/components/g-ctrl.vue +53 -54
- package/src/components/g-form.vue +46 -43
- package/src/components/g-query-item.vue +11 -10
- package/src/components/g-query.vue +49 -32
- package/src/components/g-table.vue +223 -160
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue-2024-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/components/index.js",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"preview": "vite preview"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"@element-plus/icons-vue": "^2.3.1",
|
|
21
22
|
"element-plus": "^2.8.4",
|
|
22
23
|
"vue": "^3.4.29"
|
|
23
24
|
},
|
|
@@ -2,90 +2,90 @@
|
|
|
2
2
|
<div style="display: flex; width: 100%;" class="g-ctrl-container">
|
|
3
3
|
<!--radio-->
|
|
4
4
|
<el-radio-group v-model="ctrlValue" v-bind="itemInfo" v-if="ctrlType == 'radio'">
|
|
5
|
-
<slot :name="`${ctrlKey}
|
|
6
|
-
<el-radio v-bind="option" v-for="option in
|
|
7
|
-
<slot :name="`${ctrlKey}-
|
|
5
|
+
<slot :name="`${props.t}-${ctrlKey}`" :data="itemInfo">
|
|
6
|
+
<el-radio v-bind="option" v-for="option in model[ctrlKey].options">
|
|
7
|
+
<slot :name="`${props.t}-${ctrlKey}-options`" :option></slot>
|
|
8
8
|
</el-radio>
|
|
9
9
|
</slot>
|
|
10
10
|
</el-radio-group>
|
|
11
11
|
<!--radio-button-->
|
|
12
12
|
<el-radio-group v-model="ctrlValue" v-bind="itemInfo" v-else-if="ctrlType == 'radio-button'">
|
|
13
|
-
<slot :name="`${ctrlKey}
|
|
14
|
-
<el-radio-button v-bind="option" v-for="option in
|
|
15
|
-
<slot :name="`${ctrlKey}-
|
|
13
|
+
<slot :name="`${props.t}-${ctrlKey}`" :data="itemInfo">
|
|
14
|
+
<el-radio-button v-bind="option" v-for="option in model[ctrlKey].options">
|
|
15
|
+
<slot :name="`${props.t}-${ctrlKey}-options`" :option></slot>
|
|
16
16
|
</el-radio-button>
|
|
17
17
|
</slot>
|
|
18
18
|
</el-radio-group>
|
|
19
19
|
<!--checkbox-->
|
|
20
20
|
<el-checkbox v-model="ctrlValue" v-bind="itemInfo" v-else-if="ctrlType == 'checkbox'">
|
|
21
|
-
<slot :name="`${ctrlKey}
|
|
21
|
+
<slot :name="`${props.t}-${ctrlKey}`" :data="itemInfo">{{ " " }}</slot>
|
|
22
22
|
</el-checkbox>
|
|
23
23
|
<!--checkbox-group-->
|
|
24
24
|
<el-checkbox-group v-model="ctrlValue" v-bind="itemInfo" v-else-if="ctrlType == 'checkbox-group'">
|
|
25
|
-
<slot :name="`${ctrlKey}
|
|
26
|
-
<el-checkbox v-bind="option" v-for="option in
|
|
27
|
-
<slot :name="`${ctrlKey}-
|
|
25
|
+
<slot :name="`${props.t}-${ctrlKey}`" :data="itemInfo">
|
|
26
|
+
<el-checkbox v-bind="option" v-for="option in model[ctrlKey].options">
|
|
27
|
+
<slot :name="`${props.t}-${ctrlKey}-options`" :option>{{ option.label }}</slot>
|
|
28
28
|
</el-checkbox>
|
|
29
29
|
</slot>
|
|
30
30
|
</el-checkbox-group>
|
|
31
31
|
<!--checkbox-group-button-->
|
|
32
32
|
<el-checkbox-group v-model="ctrlValue" v-bind="itemInfo" v-else-if="ctrlType == 'checkbox-group-button'">
|
|
33
|
-
<slot :name="`${ctrlKey}
|
|
34
|
-
<el-checkbox-button v-bind="option" v-for="option in
|
|
35
|
-
<slot :name="`${ctrlKey}-
|
|
33
|
+
<slot :name="`${props.t}-${ctrlKey}`" :data="itemInfo">
|
|
34
|
+
<el-checkbox-button v-bind="option" v-for="option in model[ctrlKey].options">
|
|
35
|
+
<slot :name="`${props.t}-${ctrlKey}-options`" :option></slot>
|
|
36
36
|
</el-checkbox-button>
|
|
37
37
|
</slot>
|
|
38
38
|
</el-checkbox-group>
|
|
39
39
|
<!--select-->
|
|
40
|
-
<el-select v-model="ctrlValue" :placeholder="
|
|
40
|
+
<el-select v-model="ctrlValue" :placeholder="model[ctrlKey].label" v-bind="selectModel"
|
|
41
41
|
v-else-if="ctrlType == 'select'">
|
|
42
|
-
<template #default v-if="
|
|
43
|
-
<slot :name="`${ctrlKey}
|
|
44
|
-
<el-option-group v-for="group in
|
|
42
|
+
<template #default v-if="model[ctrlKey]?.options?.some(a => a.options)">
|
|
43
|
+
<slot :name="`${props.t}-${ctrlKey}`" :options="model[ctrlKey].options">
|
|
44
|
+
<el-option-group v-for="group in model[ctrlKey].options" :label="group.label">
|
|
45
45
|
<el-option v-bind="option" v-for="option in group.options"
|
|
46
46
|
@click.native="selectModel.change && selectModel.change(option)">
|
|
47
|
-
<slot :name="`${ctrlKey}-
|
|
47
|
+
<slot :name="`${props.t}-${ctrlKey}-options`" :option></slot>
|
|
48
48
|
</el-option>
|
|
49
49
|
</el-option-group>
|
|
50
50
|
</slot>
|
|
51
51
|
</template>
|
|
52
52
|
<template #default v-else>
|
|
53
|
-
<slot :name="`${ctrlKey}
|
|
54
|
-
<el-option v-bind="option" v-for="option in
|
|
53
|
+
<slot :name="`${props.t}-${ctrlKey}`" :options="model[ctrlKey].options">
|
|
54
|
+
<el-option v-bind="option" v-for="option in model[ctrlKey].options"
|
|
55
55
|
@click.native="selectModel.change && selectModel.change(option)">
|
|
56
|
-
<slot :name="`${ctrlKey}-
|
|
56
|
+
<slot :name="`${props.t}-${ctrlKey}-options`" :option></slot>
|
|
57
57
|
</el-option>
|
|
58
58
|
</slot>
|
|
59
59
|
</template>
|
|
60
60
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
61
|
-
<slot :name="`${ctrlKey}
|
|
61
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
62
62
|
</template>
|
|
63
63
|
</el-select>
|
|
64
64
|
<!--tree-select-->
|
|
65
|
-
<el-tree-select v-model="ctrlValue" :placeholder="
|
|
65
|
+
<el-tree-select v-model="ctrlValue" :placeholder="model[ctrlKey].label" v-bind="itemInfo"
|
|
66
66
|
v-else-if="ctrlType == 'tree-select'">
|
|
67
67
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
68
|
-
<slot :name="`${ctrlKey}
|
|
68
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
69
69
|
</template>
|
|
70
70
|
</el-tree-select>
|
|
71
71
|
<!--time-->
|
|
72
|
-
<el-time-picker v-model="ctrlValue" arrow-control v-bind="itemInfo" :placeholder="
|
|
72
|
+
<el-time-picker v-model="ctrlValue" arrow-control v-bind="itemInfo" :placeholder="model[ctrlKey].label"
|
|
73
73
|
v-else-if="ctrlType == 'time'" />
|
|
74
74
|
<!--time-select-->
|
|
75
|
-
<el-time-select v-model="ctrlValue" start="06:30" step="00:15" end="23:30" :placeholder="
|
|
75
|
+
<el-time-select v-model="ctrlValue" start="06:30" step="00:15" end="23:30" :placeholder="model[ctrlKey].label"
|
|
76
76
|
v-bind="itemInfo" v-else-if="ctrlType == 'time-select'" />
|
|
77
77
|
<!--date-->
|
|
78
|
-
<el-date-picker v-model="ctrlValue" type="date" :placeholder="
|
|
78
|
+
<el-date-picker v-model="ctrlValue" type="date" :placeholder="model[ctrlKey].label" v-bind="itemInfo"
|
|
79
79
|
v-else-if="ctrlType == 'date'">
|
|
80
80
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
81
|
-
<slot :name="`${ctrlKey}
|
|
81
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
82
82
|
</template>
|
|
83
83
|
</el-date-picker>
|
|
84
84
|
<!--datetime-->
|
|
85
|
-
<el-date-picker v-model="ctrlValue" type="datetime" :placeholder="
|
|
85
|
+
<el-date-picker v-model="ctrlValue" type="datetime" :placeholder="model[ctrlKey].label" v-bind="itemInfo"
|
|
86
86
|
v-else-if="ctrlType == 'datetime'">
|
|
87
87
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
88
|
-
<slot :name="`${ctrlKey}
|
|
88
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
89
89
|
</template>
|
|
90
90
|
</el-date-picker>
|
|
91
91
|
<!--color-->
|
|
@@ -97,46 +97,46 @@
|
|
|
97
97
|
<!--switch-->
|
|
98
98
|
<el-switch v-model="ctrlValue" v-bind="itemInfo" v-else-if="ctrlType == 'switch'">
|
|
99
99
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
100
|
-
<slot :name="`${ctrlKey}
|
|
100
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
101
101
|
</template>
|
|
102
102
|
</el-switch>
|
|
103
103
|
<!--transfer-->
|
|
104
104
|
<el-transfer v-model="ctrlValue" v-bind="itemInfo" v-else-if="ctrlType == 'transfer'">
|
|
105
105
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
106
|
-
<slot :name="`${ctrlKey}
|
|
106
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
107
107
|
</template>
|
|
108
108
|
</el-transfer>
|
|
109
109
|
<!--cascader-->
|
|
110
110
|
<el-cascader v-model="ctrlValue" v-bind="itemInfo" v-else-if="ctrlType == 'cascader'">
|
|
111
111
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
112
|
-
<slot :name="`${ctrlKey}
|
|
112
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
113
113
|
</template>
|
|
114
114
|
</el-cascader>
|
|
115
115
|
<!--upload-->
|
|
116
116
|
<el-upload v-model="ctrlValue" v-bind="itemInfo" v-else-if="ctrlType == 'upload'">
|
|
117
117
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
118
|
-
<slot :name="`${ctrlKey}
|
|
118
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
119
119
|
</template>
|
|
120
120
|
</el-upload>
|
|
121
121
|
<!--autocomplete-->
|
|
122
|
-
<el-autocomplete v-model="ctrlValue" v-bind="itemInfo" :placeholder="
|
|
122
|
+
<el-autocomplete v-model="ctrlValue" v-bind="itemInfo" :placeholder="model[ctrlKey].label"
|
|
123
123
|
v-else-if="ctrlType == 'autocomplete'">
|
|
124
124
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
125
|
-
<slot :name="`${ctrlKey}
|
|
125
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
126
126
|
</template>
|
|
127
127
|
</el-autocomplete>
|
|
128
128
|
<!--input-number-->
|
|
129
|
-
<el-input-number v-model="ctrlValue" :min="0" :max="100000000" :placeholder="
|
|
130
|
-
v-else-if="ctrlType == 'input-number'">
|
|
129
|
+
<el-input-number v-model="ctrlValue" :min="0" :max="100000000" :placeholder="model[ctrlKey].label"
|
|
130
|
+
v-bind="itemInfo" v-else-if="ctrlType == 'input-number'">
|
|
131
131
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
132
|
-
<slot :name="`${ctrlKey}
|
|
132
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
133
133
|
</template>
|
|
134
134
|
</el-input-number>
|
|
135
135
|
<!--input-->
|
|
136
|
-
<el-input v-model="ctrlValue" :placeholder="
|
|
137
|
-
v-bind="itemInfo" v-else>
|
|
136
|
+
<el-input v-model="ctrlValue" :placeholder="model[ctrlKey].label" :maxlength="itemInfo?.max || 25"
|
|
137
|
+
:clearable="true" v-bind="itemInfo" v-else>
|
|
138
138
|
<template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
|
|
139
|
-
<slot :name="`${ctrlKey}
|
|
139
|
+
<slot :name="`${props.t}-${ctrlKey}-${slot}`" :data> </slot>
|
|
140
140
|
</template>
|
|
141
141
|
</el-input>
|
|
142
142
|
</div>
|
|
@@ -144,22 +144,21 @@
|
|
|
144
144
|
|
|
145
145
|
<script setup>
|
|
146
146
|
defineOptions({ inheritAttrs: false });
|
|
147
|
-
import { onMounted,
|
|
147
|
+
import { onMounted, useSlots } from "vue";
|
|
148
148
|
import { filterObject } from ".";
|
|
149
149
|
const ctrlValue = defineModel({ required: true });
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
const ctrlKey =
|
|
153
|
-
const ctrlType =
|
|
154
|
-
const model =
|
|
155
|
-
const slots = () => Object.keys(useSlots()).filter(a => a.startsWith(ctrlKey)).
|
|
150
|
+
const props = defineProps(["t", "ctrlKey", "item", "model", 'ctrlType'])
|
|
151
|
+
const itemInfo = props.item;
|
|
152
|
+
const ctrlKey = props.ctrlKey;
|
|
153
|
+
const ctrlType = props.ctrlType;
|
|
154
|
+
const model = props.model;
|
|
155
|
+
const slots = () => Object.keys(useSlots()).filter(a => a.startsWith(`${props.t}-${ctrlKey}-`)).map(a => a.replace(`${props.t}-${ctrlKey}-`, ''));
|
|
156
156
|
|
|
157
157
|
//select 默认属性
|
|
158
158
|
const selectModel = {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}, ...itemInfo
|
|
159
|
+
filterable: true,
|
|
160
|
+
remote: itemInfo && itemInfo["remote-method"] ? true : false,
|
|
161
|
+
...itemInfo
|
|
163
162
|
};
|
|
164
163
|
const selectRemoteMethod = (query) => {
|
|
165
164
|
itemInfo["remote-method"](query, (a) => {
|
|
@@ -168,7 +167,7 @@ const selectRemoteMethod = (query) => {
|
|
|
168
167
|
}
|
|
169
168
|
|
|
170
169
|
onMounted(() => {
|
|
171
|
-
if (itemInfo["remote-method"]) {
|
|
170
|
+
if (itemInfo && itemInfo["remote-method"]) {
|
|
172
171
|
selectModel['remote-method'] = selectRemoteMethod;
|
|
173
172
|
}
|
|
174
173
|
})
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<el-form ref="gform" :model="model"
|
|
3
|
-
v-bind="filterObject(model.form, k => !['
|
|
2
|
+
<el-form ref="gform" :model="model" :style="{ width: '98%', padding: 0, margin: 0, 'box-sizing': 'border-box' }"
|
|
3
|
+
v-bind="filterObject(model.form, k => !['footer', 'submit', 'reset', 'slots', 'type', 'sort'].includes(k))"
|
|
4
4
|
class="g-form-container">
|
|
5
5
|
<slot>
|
|
6
|
-
<el-
|
|
7
|
-
|
|
8
|
-
:
|
|
9
|
-
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
6
|
+
<el-col v-bind="{ ...model.form.cols, ...item.col }" v-for="(item, key) of items" :key="key"
|
|
7
|
+
style="width: 100%;">
|
|
8
|
+
<el-form-item :label="item.label" :prop="`${key}.value`" :rules="getItemRulesByItem(item)"
|
|
9
|
+
v-bind="{ ...model?.formItems, ...item?.formItem }" style="width:100%;">
|
|
10
|
+
<slot :name="'f-' + key" :item :model>
|
|
11
|
+
<g-ctrl v-model="model[key].value" :item="item?.editor" :ctrlKey="key" :ctrlType="item.type"
|
|
12
|
+
:model class="g-ctrl-container" t="f">
|
|
13
|
+
<template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
|
|
14
|
+
<slot :name="slotKey" :data :item :model></slot>
|
|
15
|
+
</template>
|
|
16
|
+
</g-ctrl>
|
|
17
|
+
</slot>
|
|
18
|
+
<template #label="data">
|
|
19
|
+
<slot :name="`f-${key}-label`" :data :item :model>{{ item.label }}</slot>
|
|
20
|
+
</template>
|
|
21
|
+
</el-form-item>
|
|
22
|
+
</el-col>
|
|
23
|
+
<slot name="f-footer" v-if="!model.form.footer.hidden">
|
|
21
24
|
<div :style="model.form.footer.style">
|
|
22
|
-
<slot name="footer-left"></slot>
|
|
25
|
+
<slot name="f-footer-left"></slot>
|
|
23
26
|
<el-button @click.stop="model.form.submit.click(formInfo, model)"
|
|
24
27
|
v-bind="filterObject(model.form.submit, k => !['click'].includes(k))"
|
|
25
28
|
v-if="!model?.form?.submit?.hidden">
|
|
@@ -30,7 +33,7 @@
|
|
|
30
33
|
v-if="!model?.form?.reset?.hidden">{{
|
|
31
34
|
model?.form?.reset?.label
|
|
32
35
|
}}</el-button>
|
|
33
|
-
<slot name="footer-right"></slot>
|
|
36
|
+
<slot name="f-footer-right"></slot>
|
|
34
37
|
</div>
|
|
35
38
|
</slot>
|
|
36
39
|
</slot>
|
|
@@ -38,17 +41,16 @@
|
|
|
38
41
|
</template>
|
|
39
42
|
|
|
40
43
|
<script setup>
|
|
41
|
-
import { computed,
|
|
44
|
+
import { computed, inject, onMounted, ref, useAttrs, watch } from "vue";
|
|
42
45
|
import gCtrl from "./g-ctrl.vue";
|
|
43
|
-
import {
|
|
46
|
+
import { mergeObjects, filterObject } from "./index";
|
|
44
47
|
defineOptions({
|
|
45
48
|
name: "g-form",
|
|
46
49
|
inheritAttrs: false
|
|
47
50
|
})
|
|
48
51
|
const model = defineModel({ required: true });
|
|
49
|
-
const emits = defineEmits(["
|
|
52
|
+
const emits = defineEmits(["submit", "reset"]);
|
|
50
53
|
const gform = ref(null);
|
|
51
|
-
let marginRight = ref(32);
|
|
52
54
|
const options = inject('options');
|
|
53
55
|
|
|
54
56
|
const defaultFormAttrs = {
|
|
@@ -58,10 +60,11 @@ const defaultFormAttrs = {
|
|
|
58
60
|
"label-width": "100px",
|
|
59
61
|
"status-icon": true,
|
|
60
62
|
"scroll-into-view-options": true,
|
|
61
|
-
columns: 2,
|
|
62
63
|
style: {
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
display: "flex",
|
|
65
|
+
flexWrap: "wrap",
|
|
66
|
+
...useAttrs()?.style,
|
|
67
|
+
|
|
65
68
|
},
|
|
66
69
|
// 表单底部属性
|
|
67
70
|
footer: {
|
|
@@ -81,8 +84,7 @@ const defaultFormAttrs = {
|
|
|
81
84
|
if (!gform.value) return
|
|
82
85
|
await gform.value.validate((valid, fields) => {
|
|
83
86
|
if (valid) {
|
|
84
|
-
emits("
|
|
85
|
-
console.log("提交");
|
|
87
|
+
emits("submit", formInfo, model);
|
|
86
88
|
} else {
|
|
87
89
|
console.log('表单验证不通过!', fields);
|
|
88
90
|
}
|
|
@@ -115,6 +117,7 @@ model.value.form = mergeObjects(
|
|
|
115
117
|
);
|
|
116
118
|
const defaultFormItemsAttrs = {
|
|
117
119
|
type: "hidden",
|
|
120
|
+
labelPosition: "right",
|
|
118
121
|
style: {
|
|
119
122
|
width: "100%",
|
|
120
123
|
}
|
|
@@ -122,9 +125,20 @@ const defaultFormItemsAttrs = {
|
|
|
122
125
|
model.value.formItems = mergeObjects(
|
|
123
126
|
defaultFormItemsAttrs,
|
|
124
127
|
options?.formItems,
|
|
125
|
-
model?.formItems
|
|
128
|
+
model?.value?.formItems
|
|
126
129
|
);
|
|
127
130
|
|
|
131
|
+
const defaultColsAttrs = {
|
|
132
|
+
span: 12,
|
|
133
|
+
offset: 0
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
model.value.form.cols = mergeObjects(
|
|
137
|
+
defaultColsAttrs,
|
|
138
|
+
options?.form?.cols,
|
|
139
|
+
model.value.form.cols
|
|
140
|
+
)
|
|
141
|
+
|
|
128
142
|
//获取表单项验证规则
|
|
129
143
|
const getItemRulesByItem = (item) => {
|
|
130
144
|
// 组装验证规则
|
|
@@ -214,32 +228,21 @@ onMounted(() => {
|
|
|
214
228
|
})
|
|
215
229
|
|
|
216
230
|
const load = () => {
|
|
217
|
-
|
|
218
|
-
model.value.form.columns = 1;
|
|
219
|
-
}
|
|
231
|
+
|
|
220
232
|
for (const [key, value] of Object.entries(items.value)) {
|
|
221
233
|
model.value[key].formItem = { ...model.value[key].formItem, ...value.formItem };
|
|
222
234
|
model.value[key].formItem.style = { ...model.value[key].formItem.style, ...value.formItem.style };
|
|
223
235
|
|
|
224
|
-
const columnWidth = value.columns && value.columns > 1 ?
|
|
225
|
-
columnsWidth.value * value.columns - (value.columns - 1) * marginRight.value :
|
|
226
|
-
columnsWidth.value - marginRight.value;
|
|
227
|
-
model.value[key].formItem.style.width = `calc(${columnWidth}px)`;
|
|
228
236
|
}
|
|
229
237
|
};
|
|
230
238
|
|
|
231
|
-
onBeforeUnmount(() => {
|
|
232
|
-
console.log('destroy');
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
watch(() => model.value.form.columns, () => load());
|
|
236
239
|
watch(() => model.value.form.inline, () => load());
|
|
237
240
|
|
|
238
|
-
|
|
241
|
+
|
|
239
242
|
//表单项
|
|
240
243
|
const items = computed(() => Object.fromEntries(Object.entries(model.value)
|
|
241
244
|
.filter(a => a[1].type != "hidden")
|
|
242
|
-
.filter(a => (a[1].
|
|
245
|
+
.filter(a => (a[1].editor !== false))
|
|
243
246
|
.filter(a => (a[1].type !== "control"))
|
|
244
247
|
.map(key => [key[0], key[1]])));
|
|
245
248
|
//表单提交对象
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<template v-for="(item, key) of getQueryModel(props.more)" :key="key">
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
<g-ctrl v-model="queryModel[key]" :item :ctrlKey="key" :model
|
|
3
|
+
<el-col v-bind="{ ...model.query.cols, ...item?.search?.col }">
|
|
4
|
+
<slot :name="`q-${key}`" :item :model>
|
|
5
|
+
<el-form-item :label="item.label" v-bind="{ ...model.queryItems, ...item?.search }">
|
|
6
|
+
<g-ctrl v-model="queryModel[key]" :item="item?.editor" :ctrlKey="key" :ctrlType="item.type" :model
|
|
7
|
+
t="q">
|
|
7
8
|
<template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
|
|
8
9
|
<slot :name="slotKey" :data :item :model></slot>
|
|
9
10
|
</template>
|
|
10
11
|
</g-ctrl>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
</
|
|
15
|
-
</
|
|
16
|
-
</
|
|
12
|
+
<template #label>
|
|
13
|
+
<slot :name="`q-${key}-label`" :item :model></slot>
|
|
14
|
+
</template>
|
|
15
|
+
</el-form-item>
|
|
16
|
+
</slot>
|
|
17
|
+
</el-col>
|
|
17
18
|
</template>
|
|
18
19
|
</template>
|
|
19
20
|
|
|
@@ -6,35 +6,41 @@
|
|
|
6
6
|
<slot :name="slotKey" :model></slot>
|
|
7
7
|
</template>
|
|
8
8
|
</g-query-item>
|
|
9
|
-
<el-
|
|
10
|
-
<el-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<el-popover v-bind="model.query.more.dialog" v-if="model.query.more.mode == 3">
|
|
21
|
-
<template #reference>
|
|
22
|
-
<el-button v-bind="model.query.more">
|
|
9
|
+
<el-col v-bind="model.query.btns.col" style="width:100%;">
|
|
10
|
+
<el-form-item style="width: 100%;">
|
|
11
|
+
<div :style="model.query.btns.style">
|
|
12
|
+
<el-button v-bind="model.query.query" @click="model.query.query.click()">
|
|
13
|
+
{{ model.query.query.label }}
|
|
14
|
+
</el-button>
|
|
15
|
+
<el-button v-bind="model.query.reset" @click="model.query.reset.click()">
|
|
16
|
+
{{ model.query.reset.label }}
|
|
17
|
+
</el-button>
|
|
18
|
+
<el-button v-bind="model.query.more" @click="model.query.more.click()"
|
|
19
|
+
v-if="model.query.more.mode !== 3">
|
|
23
20
|
{{ model.query.more.label }}
|
|
24
21
|
</el-button>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
22
|
+
<el-popover v-bind="model.query.more.dialog" v-if="model.query.more.mode == 3">
|
|
23
|
+
<template #reference>
|
|
24
|
+
<el-button v-bind="model.query.more">
|
|
25
|
+
{{ model.query.more.label }}
|
|
26
|
+
</el-button>
|
|
27
|
+
</template>
|
|
28
|
+
<template #default>
|
|
29
|
+
<el-form
|
|
30
|
+
v-bind="filterObject(model.query, k => !['query', 'more', 'reset'].includes(k))">
|
|
31
|
+
<g-query-item v-model="model" v-model:info="queryModel" :more="true">
|
|
32
|
+
<template v-for="(slot, slotKey, index) in $slots" :key="index"
|
|
33
|
+
#[slotKey]="data">
|
|
34
|
+
<slot :name="slotKey" :model></slot>
|
|
35
|
+
</template>
|
|
36
|
+
</g-query-item>
|
|
37
|
+
</el-form>
|
|
38
|
+
</template>
|
|
39
|
+
</el-popover>
|
|
40
|
+
<slot name="q-btns"></slot>
|
|
41
|
+
</div>
|
|
42
|
+
</el-form-item>
|
|
43
|
+
</el-col>
|
|
38
44
|
</el-form>
|
|
39
45
|
<Transition :duration="300" name="nested">
|
|
40
46
|
<div v-if="isShowMore && !model.query.more.hidden && model.query.more.mode == 1" class="outer">
|
|
@@ -52,7 +58,8 @@
|
|
|
52
58
|
</Transition>
|
|
53
59
|
<el-drawer v-model="isShowMore" title="更多查询" :show-close="false" v-bind="model.query.more.dialog"
|
|
54
60
|
v-if="isShowMore && !model.query.more.hidden && model.query.more.mode == 2">
|
|
55
|
-
<el-form v-bind="filterObject(model.query, k => !['query', 'more', 'reset'].includes(k))"
|
|
61
|
+
<el-form v-bind="filterObject(model.query, k => !['query', 'more', 'reset'].includes(k))"
|
|
62
|
+
style="width:98%;">
|
|
56
63
|
<g-query-item v-model="model" v-model:info="queryModel" :more="true">
|
|
57
64
|
<template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
|
|
58
65
|
<slot :name="slotKey" :model></slot>
|
|
@@ -116,6 +123,15 @@ const defaultQueryAttrs = {
|
|
|
116
123
|
emits('query', queryModel.value);
|
|
117
124
|
isShowMore.value = false;
|
|
118
125
|
}
|
|
126
|
+
},
|
|
127
|
+
cols: {
|
|
128
|
+
span: 6, offset: 0, xs: 24, sm: 12, md: 6, lg: 6, xl: 4,
|
|
129
|
+
},
|
|
130
|
+
btns: {
|
|
131
|
+
col: { span: 6, offset: 0, xs: 24, sm: 12, md: 6, lg: 6, xl: 4, },
|
|
132
|
+
style: {
|
|
133
|
+
width: "100%", display: "flex", justifyContent: "flex-end"
|
|
134
|
+
}
|
|
119
135
|
}
|
|
120
136
|
}
|
|
121
137
|
|
|
@@ -137,8 +153,9 @@ model.value.query.more.dialog = model.value.query.more.mode == 2 ? mergeObjects(
|
|
|
137
153
|
const defaultQueryItemsAttrs = {
|
|
138
154
|
type: "hidden",
|
|
139
155
|
labelPosition: 'right',
|
|
156
|
+
span: 8,
|
|
140
157
|
style: {
|
|
141
|
-
width: "
|
|
158
|
+
width: "100%"
|
|
142
159
|
}
|
|
143
160
|
};
|
|
144
161
|
model.value.queryItems = mergeObjects(defaultQueryItemsAttrs, options?.queryItems, model.value.queryItems);
|
|
@@ -167,14 +184,14 @@ model.value.queryItems = mergeObjects(defaultQueryItemsAttrs, options?.queryItem
|
|
|
167
184
|
}
|
|
168
185
|
|
|
169
186
|
.inner {
|
|
170
|
-
border-radius:
|
|
187
|
+
border-radius: 6px;
|
|
171
188
|
min-height: 100px;
|
|
172
189
|
border: 1px solid #f2f2f2;
|
|
173
190
|
padding: 20px;
|
|
174
191
|
box-sizing: border-box;
|
|
175
192
|
width: 100%;
|
|
176
|
-
background-color: rgba(255, 255, 255,
|
|
177
|
-
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
|
193
|
+
background-color: rgba(255, 255, 255, 0.8);
|
|
194
|
+
/*box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); */
|
|
178
195
|
}
|
|
179
196
|
|
|
180
197
|
.nested-enter-active,
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="table-query-container">
|
|
3
3
|
<slot name="query">
|
|
4
|
-
<g-query v-model="model" @query="query" @reset="
|
|
4
|
+
<g-query v-model="model" @query="query" @reset="queryReset">
|
|
5
5
|
<template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
|
|
6
6
|
<slot :name="slotKey" :model></slot>
|
|
7
7
|
</template>
|
|
8
|
-
<template #btns>
|
|
9
|
-
<slot name="btns">
|
|
8
|
+
<template #q-btns>
|
|
9
|
+
<slot name="q-btns">
|
|
10
10
|
<div class="btns" v-if="model.control.add.auth()">
|
|
11
11
|
<slot name="control-add-left"></slot>
|
|
12
12
|
<slot name="control-add">
|
|
13
|
-
<el-button v-bind="model.control.add" @click="
|
|
13
|
+
<el-button v-bind="model.control.add" @click="addRow(model)">{{
|
|
14
14
|
model.control.add.label
|
|
15
15
|
}}</el-button>
|
|
16
16
|
</slot>
|
|
@@ -21,12 +21,13 @@
|
|
|
21
21
|
</template>
|
|
22
22
|
</g-query>
|
|
23
23
|
</slot>
|
|
24
|
-
|
|
25
24
|
</div>
|
|
26
|
-
<el-table class="g-table-container"
|
|
25
|
+
<el-table class="g-table-container"
|
|
26
|
+
v-bind="{ ...$attrs, ...filterObject(model.table, k => !['dblclickType', 'page'].includes(k)) }">
|
|
27
27
|
<slot>
|
|
28
28
|
<el-table-column :prop="key" v-for="(value, key) of tableColumns" :key="key"
|
|
29
|
-
v-bind="{ ...model.tableColumns, ...value }"
|
|
29
|
+
v-bind="{ ...model.tableColumns, ...filterObject(value, k => tableColumnsAttrs.includes(k)) }"
|
|
30
|
+
header-align="center">
|
|
30
31
|
<template #default="{ row, column, $index }"
|
|
31
32
|
v-if="value.type != 'selection' && value.type != 'index' && value.type != 'expand'">
|
|
32
33
|
<slot :name="`${key}`" :row :column :$index>
|
|
@@ -34,29 +35,27 @@
|
|
|
34
35
|
</slot>
|
|
35
36
|
</template>
|
|
36
37
|
<template #default="{ row, column, $index }" v-if="value.type == 'control'">
|
|
37
|
-
<div class="control"
|
|
38
|
+
<div class="control" :class="model.control?.class" :style="model.control?.style">
|
|
38
39
|
<slot name="control">
|
|
39
40
|
<slot name="control-left" :row :column :$index> </slot>
|
|
40
41
|
<slot name="control-view" :row :column :$index
|
|
41
42
|
v-if="model.control.view.auth(row, column, $index)">
|
|
42
|
-
<el-button v-bind="model.control.view"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}}</el-button>
|
|
43
|
+
<el-button v-bind="model.control.view" @click="readForm(row, column, $index, model)">{{
|
|
44
|
+
model.control.view.label
|
|
45
|
+
}}</el-button>
|
|
46
46
|
</slot>
|
|
47
47
|
<slot name="control-edit-left" :row :column :$index> </slot>
|
|
48
48
|
<slot name="control-edit" :row :column :$index
|
|
49
49
|
v-if="model.control.edit.auth(row, column, $index)">
|
|
50
|
-
<el-button v-bind="model.control.edit"
|
|
51
|
-
|
|
52
|
-
model.control.edit.label
|
|
50
|
+
<el-button v-bind="model.control.edit" @click="editRow(row, column, $index, model)">{{
|
|
51
|
+
model.control.edit.label
|
|
53
52
|
}}</el-button>
|
|
54
53
|
</slot>
|
|
55
54
|
<slot name="control-edit-right" :row :column :$index> </slot>
|
|
56
55
|
<slot name="control-delete" :row :column :$index
|
|
57
56
|
v-if="model.control.delete.auth(row, column, $index)">
|
|
58
57
|
<el-button v-bind="model.control.delete"
|
|
59
|
-
@click="
|
|
58
|
+
@click="deleteRow(row, column, $index, model)">{{
|
|
60
59
|
model.control.delete.label }}</el-button>
|
|
61
60
|
</slot>
|
|
62
61
|
<slot name="control-right" :row :column :$index> </slot>
|
|
@@ -84,27 +83,85 @@
|
|
|
84
83
|
<slot name="table-page"></slot>
|
|
85
84
|
</el-pagination>
|
|
86
85
|
</slot>
|
|
86
|
+
<div v-show="model.dialog.mode == 'dialog'">
|
|
87
|
+
<el-dialog v-model="dialogVisible" :fullscreen="model.dialog.fullScreen"
|
|
88
|
+
v-bind="filterObject(model.dialog, k => !['size'].includes(k))"
|
|
89
|
+
:width="convertToPx(model.dialog.width) + 35">
|
|
90
|
+
<template #header>
|
|
91
|
+
<div style="display: flex;margin-top: -2px;">
|
|
92
|
+
<div style="display: flex;flex:1;">
|
|
93
|
+
<slot name="f-header">
|
|
94
|
+
<div>{{ model.dialog.title }}</div>
|
|
95
|
+
</slot>
|
|
96
|
+
</div>
|
|
97
|
+
<!--最大化-->
|
|
98
|
+
<div v-if="model?.dialog?.fullScreen === false" @click="model.dialog.fullScreen = true;"
|
|
99
|
+
class="max">
|
|
100
|
+
<el-icon>
|
|
101
|
+
<FullScreen />
|
|
102
|
+
</el-icon>
|
|
103
|
+
</div>
|
|
104
|
+
<!--最小化-->
|
|
105
|
+
<div v-if="model?.dialog?.fullScreen === true" @click="model.dialog.fullScreen = false;"
|
|
106
|
+
class="max">
|
|
107
|
+
<el-icon>
|
|
108
|
+
<Remove />
|
|
109
|
+
</el-icon>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
</template>
|
|
114
|
+
<div style="display: flex; justify-content: center; width: 100%; height: 100%;" id="table-form">
|
|
115
|
+
<g-form v-model="model" @submit="submit" @reset="formReset">
|
|
116
|
+
<template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
|
|
117
|
+
<slot :name="slotKey" :model="data"></slot>
|
|
118
|
+
</template>
|
|
119
|
+
</g-form>
|
|
120
|
+
</div>
|
|
121
|
+
</el-dialog>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<div v-show="model.dialog.mode == 'drawer'">
|
|
125
|
+
<el-drawer v-model="dialogVisible" v-bind="filterObject(model.dialog, k => !['width'].includes(k))">
|
|
126
|
+
<template #header>
|
|
127
|
+
<div style="display: flex;">
|
|
128
|
+
<div style="display: flex;flex:1;">
|
|
129
|
+
<slot name="f-header">
|
|
130
|
+
<div>{{ model.dialog.title }}</div>
|
|
131
|
+
</slot>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</template>
|
|
135
|
+
<g-form v-model="model" @submit="submit" @reset="formReset">
|
|
136
|
+
<template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
|
|
137
|
+
<slot :name="slotKey" :model="data"></slot>
|
|
138
|
+
</template>
|
|
139
|
+
</g-form>
|
|
140
|
+
</el-drawer>
|
|
141
|
+
</div>
|
|
87
142
|
</template>
|
|
88
143
|
|
|
89
144
|
<script setup>
|
|
90
145
|
import dayjs from 'dayjs';
|
|
91
146
|
import { ElMessageBox } from 'element-plus';
|
|
92
|
-
import { computed, watchEffect, inject, ref
|
|
147
|
+
import { computed, watchEffect, inject, ref } from 'vue';
|
|
93
148
|
import GForm from './g-form.vue';
|
|
94
149
|
import gQuery from './g-query.vue';
|
|
95
|
-
import {
|
|
150
|
+
import { mergeObjects, filterObject, convertToPx } from './index';
|
|
151
|
+
import { FullScreen, Remove } from '@element-plus/icons-vue';
|
|
96
152
|
|
|
97
153
|
defineOptions({
|
|
98
154
|
name: "g-table",
|
|
99
155
|
inheritAttrs: false
|
|
100
156
|
})
|
|
101
|
-
|
|
102
|
-
const emits = defineEmits(['load', 'view', "edit", "delete", 'add']);
|
|
157
|
+
const emits = defineEmits(['load', 'view', "edit", "delete", 'add', 'submit', 'reset']);
|
|
103
158
|
const model = defineModel({ required: true });
|
|
104
159
|
const options = inject('options');
|
|
105
160
|
const queryInfo = ref({});
|
|
161
|
+
const dialogVisible = ref(false);
|
|
162
|
+
const tableColumnsAttrs = ['type', 'index', 'label', 'column-key', 'prop', 'width', 'min-width', 'fixed', 'render-header', 'sortable', 'sort-method', 'sort-by', 'sort-orders', 'resizable', 'formatter', 'show-overflow-tooltip', 'align', 'header-align', 'class-name', 'label-class-name', 'selectable', 'reserve-selection', 'filters', 'filter-placement', 'filter-class-name', 'filter-multiple', 'filter-method', 'filtered-value'];
|
|
106
163
|
|
|
107
|
-
|
|
164
|
+
//合并表格属性包括分页
|
|
108
165
|
const defaultTableAttrs = {
|
|
109
166
|
data: [],
|
|
110
167
|
border: true,
|
|
@@ -120,8 +177,14 @@ const defaultTableAttrs = {
|
|
|
120
177
|
model.value.table.page.total = total;
|
|
121
178
|
});
|
|
122
179
|
},
|
|
180
|
+
onRowDblclick: (row, column, event) => {
|
|
181
|
+
if (model.value.table.dblclickType == 'edit') {
|
|
182
|
+
editRow(row, column, event, model);
|
|
183
|
+
} else if (model.value.table.dblclickType == 'view') {
|
|
184
|
+
readForm(row, column, event, model);
|
|
185
|
+
}
|
|
186
|
+
},
|
|
123
187
|
page: {
|
|
124
|
-
background: "red",
|
|
125
188
|
total: 0,
|
|
126
189
|
pageSize: 20,
|
|
127
190
|
currentPage: 1,
|
|
@@ -132,146 +195,37 @@ const defaultTableAttrs = {
|
|
|
132
195
|
justifyContent: 'flex-end',
|
|
133
196
|
padding: "10px",
|
|
134
197
|
},
|
|
135
|
-
}
|
|
198
|
+
},
|
|
199
|
+
dblclickType: 'edit'
|
|
136
200
|
};
|
|
137
201
|
model.value.table = mergeObjects(
|
|
138
202
|
defaultTableAttrs,
|
|
139
203
|
options?.table,
|
|
140
204
|
model.value.table
|
|
141
205
|
);
|
|
206
|
+
|
|
207
|
+
//合并功能属性
|
|
142
208
|
const defaultControl = {
|
|
143
209
|
type: 'control', label: '操作', edit: false, width: 250, fixed: 'right',
|
|
144
210
|
style: { ...model.value?.control?.style },
|
|
145
211
|
add: {
|
|
146
|
-
label: '新增', text: false, type: 'primary',
|
|
212
|
+
label: '新增', text: false, type: 'primary', mode: 'dialog',
|
|
147
213
|
style: {
|
|
148
214
|
marginLeft: "10px",
|
|
149
215
|
},
|
|
150
|
-
dialog: {
|
|
151
|
-
title: '新增',
|
|
152
|
-
mode: "drawer",
|
|
153
|
-
},
|
|
154
216
|
auth: () => true,
|
|
155
|
-
click: (m) => {
|
|
156
|
-
model.value.form = {
|
|
157
|
-
...model.value.form,
|
|
158
|
-
type: 'hidden',
|
|
159
|
-
disabled: undefined,
|
|
160
|
-
footer: { hidden: false }
|
|
161
|
-
};
|
|
162
|
-
let w = model.value?.form?.style?.width || 600;
|
|
163
|
-
if (model.value.control.add.dialog.mode == "drawer") {
|
|
164
|
-
model.value.control.add.dialog.size = convertToPx(w) + 45;
|
|
165
|
-
} else {
|
|
166
|
-
model.value.control.add.dialog.width = convertToPx(w) + 35;
|
|
167
|
-
}
|
|
168
|
-
emits("add", m);
|
|
169
|
-
Object.keys(initFormData).forEach(key => {
|
|
170
|
-
if (model.value[key]) {
|
|
171
|
-
model.value[key].value = initFormData[key];
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
let colse = openModal(
|
|
175
|
-
{
|
|
176
|
-
...model.value?.control?.add?.dialog,
|
|
177
|
-
slots: {
|
|
178
|
-
default: () => h(GForm, {
|
|
179
|
-
modelValue: model.value,
|
|
180
|
-
...model.value.form,
|
|
181
|
-
key: new Date(),
|
|
182
|
-
onHandSubmit: () => {
|
|
183
|
-
colse();
|
|
184
|
-
},
|
|
185
|
-
}, { ...model.value.form.slots })
|
|
186
|
-
}
|
|
187
|
-
}, model.value?.control?.add?.dialog?.mode);
|
|
188
|
-
},
|
|
189
217
|
},
|
|
190
218
|
view: {
|
|
191
|
-
label: '查看', text: true, type: 'success',
|
|
192
|
-
dialog: {
|
|
193
|
-
title: '查看',
|
|
194
|
-
mode: "dialog",
|
|
195
|
-
},
|
|
219
|
+
label: '查看', text: true, type: 'success', mode: 'dialog',
|
|
196
220
|
auth: (row, column, $index) => {
|
|
197
221
|
return false;
|
|
198
222
|
},
|
|
199
|
-
click: (row, column, $index, m) => {
|
|
200
|
-
model.value.form = {
|
|
201
|
-
...model.value.form,
|
|
202
|
-
type: 'hidden',
|
|
203
|
-
disabled: true,
|
|
204
|
-
footer: { hidden: true }
|
|
205
|
-
};
|
|
206
|
-
let w = model.value?.form?.style?.width || 600;
|
|
207
|
-
if (model.value.control.view.dialog.mode == "drawer") {
|
|
208
|
-
model.value.control.view.dialog.size = convertToPx(w) + 45;
|
|
209
|
-
} else {
|
|
210
|
-
model.value.control.view.dialog.width = convertToPx(w) + 35;
|
|
211
|
-
}
|
|
212
|
-
emits("view", row, column, $index, m);
|
|
213
|
-
Object.keys(row).forEach(key => {
|
|
214
|
-
if (model.value[key]) {
|
|
215
|
-
model.value[key].value = row[key];
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
let colse = openModal(
|
|
219
|
-
{
|
|
220
|
-
...model.value?.control?.view?.dialog,
|
|
221
|
-
slots: {
|
|
222
|
-
default: () => h(GForm, {
|
|
223
|
-
modelValue: model.value,
|
|
224
|
-
...model.value.form,
|
|
225
|
-
onHandSubmit: () => {
|
|
226
|
-
colse();
|
|
227
|
-
},
|
|
228
|
-
}, { ...model.value.form.slots })
|
|
229
|
-
}
|
|
230
|
-
}, model.value?.control?.view?.dialog?.mode);
|
|
231
|
-
},
|
|
232
223
|
},
|
|
233
224
|
edit: {
|
|
234
|
-
label: '编辑', text: true, type: 'primary',
|
|
235
|
-
dialog: {
|
|
236
|
-
title: '编辑',
|
|
237
|
-
mode: "dialog",
|
|
238
|
-
},
|
|
225
|
+
label: '编辑', text: true, type: 'primary', mode: 'dialog',
|
|
239
226
|
auth: (row, column, $index) => {
|
|
240
227
|
return true;
|
|
241
228
|
},
|
|
242
|
-
click: (row, column, $index, m) => {
|
|
243
|
-
model.value.form = {
|
|
244
|
-
...model.value.form,
|
|
245
|
-
type: 'hidden',
|
|
246
|
-
disabled: undefined,
|
|
247
|
-
footer: { hidden: false }
|
|
248
|
-
};
|
|
249
|
-
let w = model.value?.form?.style?.width || 600;
|
|
250
|
-
if (model.value.control.edit.dialog.mode == "drawer") {
|
|
251
|
-
model.value.control.edit.dialog.size = convertToPx(w) + 45;
|
|
252
|
-
} else {
|
|
253
|
-
model.value.control.edit.dialog.width = convertToPx(w) + 35;
|
|
254
|
-
}
|
|
255
|
-
emits("edit", row, column, $index, m);
|
|
256
|
-
Object.keys(row).forEach(key => {
|
|
257
|
-
if (model.value[key]) {
|
|
258
|
-
model.value[key].value = row[key];
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
let colse = openModal(
|
|
262
|
-
{
|
|
263
|
-
...model.value?.control?.edit?.dialog,
|
|
264
|
-
slots: {
|
|
265
|
-
default: () => h(GForm, {
|
|
266
|
-
modelValue: model.value,
|
|
267
|
-
...model.value.form,
|
|
268
|
-
onHandSubmit: () => {
|
|
269
|
-
colse();
|
|
270
|
-
},
|
|
271
|
-
}, { ...model.value.form.slots })
|
|
272
|
-
}
|
|
273
|
-
}, model.value?.control?.edit?.dialog?.mode);
|
|
274
|
-
},
|
|
275
229
|
},
|
|
276
230
|
delete: {
|
|
277
231
|
text: true, label: '删除', type: 'danger',
|
|
@@ -281,27 +235,15 @@ const defaultControl = {
|
|
|
281
235
|
dialog: {
|
|
282
236
|
message: '此操作将永久删除该文件, 是否继续?', title: '提示', options: { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }
|
|
283
237
|
},
|
|
284
|
-
click: (row, column, $index) => {
|
|
285
|
-
let { message, title, options } = model.value.control.delete.dialog;
|
|
286
|
-
ElMessageBox.confirm(message, title, options).then(() => {
|
|
287
|
-
emits("delete", { row, column, $index }, (res) => {
|
|
288
|
-
if (res) {
|
|
289
|
-
model.value.table.data.splice($index, 1);
|
|
290
|
-
model.value.table.page.total--;
|
|
291
|
-
}
|
|
292
|
-
})
|
|
293
|
-
}).catch(() => { });
|
|
294
|
-
|
|
295
|
-
},
|
|
296
238
|
},
|
|
297
239
|
};
|
|
298
|
-
|
|
299
240
|
model.value.control = mergeObjects(
|
|
300
241
|
defaultControl,
|
|
301
242
|
options?.control,
|
|
302
243
|
model.value?.control
|
|
303
244
|
);
|
|
304
245
|
|
|
246
|
+
//设置表格所有列属性
|
|
305
247
|
const defaultTableColumnsAttrs = {
|
|
306
248
|
type: "hidden",
|
|
307
249
|
width: 120,
|
|
@@ -310,13 +252,40 @@ const defaultTableColumnsAttrs = {
|
|
|
310
252
|
return cellValue;
|
|
311
253
|
}
|
|
312
254
|
};
|
|
313
|
-
|
|
314
255
|
model.value.tableColumns = mergeObjects(
|
|
315
256
|
defaultTableColumnsAttrs,
|
|
316
257
|
options?.tableColumns,
|
|
317
258
|
model.value?.tableColumns
|
|
318
259
|
);
|
|
319
260
|
|
|
261
|
+
//合并表单属性
|
|
262
|
+
const defaultFormAttrs = {
|
|
263
|
+
type: 'hidden',
|
|
264
|
+
disabled: undefined,
|
|
265
|
+
footer: { hidden: false }
|
|
266
|
+
}
|
|
267
|
+
model.value.form = mergeObjects(
|
|
268
|
+
defaultFormAttrs,
|
|
269
|
+
options?.form,
|
|
270
|
+
model.value?.form
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
//合并表单弹窗属性
|
|
274
|
+
const defaultDialogAttrs = {
|
|
275
|
+
title: "编辑",
|
|
276
|
+
mode: "drawer",
|
|
277
|
+
type: 'hidden',
|
|
278
|
+
width: 700,
|
|
279
|
+
size: 700,
|
|
280
|
+
fullScreen: false
|
|
281
|
+
}
|
|
282
|
+
model.value.dialog = mergeObjects(
|
|
283
|
+
defaultDialogAttrs,
|
|
284
|
+
options?.dialog,
|
|
285
|
+
model.value?.dialog
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
//记录表单初始值
|
|
320
289
|
const initFormData = Object.fromEntries(Object.entries(filterObject(model.value, (k, val) => {
|
|
321
290
|
return (val.type != 'control' && val.edit !== false && val.type != 'hidden');
|
|
322
291
|
})).map(([key, val]) => [key, val.value]));
|
|
@@ -360,23 +329,100 @@ const formatterExtends = (item, str) => {
|
|
|
360
329
|
return trueValue
|
|
361
330
|
}
|
|
362
331
|
|
|
363
|
-
|
|
332
|
+
|
|
333
|
+
//重置查询初始值
|
|
334
|
+
const queryReset = (q) => {
|
|
364
335
|
console.log(q);
|
|
365
336
|
queryInfo.value = q.value;
|
|
366
|
-
//model.value.table.load();
|
|
367
337
|
}
|
|
368
338
|
|
|
339
|
+
//查询方法
|
|
369
340
|
const query = (q) => {
|
|
370
341
|
queryInfo.value = q;
|
|
371
|
-
//model.value.table.load();
|
|
372
342
|
}
|
|
373
343
|
|
|
344
|
+
//新增方法
|
|
345
|
+
const addRow = (m) => {
|
|
346
|
+
// model.value.dialog.width = model.value?.form?.style?.width || 600;
|
|
347
|
+
model.value.form.disabled = false;
|
|
348
|
+
model.value.dialog.mode = model.value.control.add.mode;
|
|
349
|
+
model.value.dialog.title = model.value.control.add.label;
|
|
350
|
+
emits("add", m);
|
|
351
|
+
Object.keys(initFormData).forEach(key => {
|
|
352
|
+
if (model.value[key]) {
|
|
353
|
+
model.value[key].value = initFormData[key];
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
dialogVisible.value = true;
|
|
357
|
+
};
|
|
374
358
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
359
|
+
//删除方法
|
|
360
|
+
const deleteRow = (row, column, $index, m) => {
|
|
361
|
+
if (model.value.control.delete?.click) {
|
|
362
|
+
model.value.control.delete.click(row, column, $index, m);
|
|
363
|
+
} else {
|
|
364
|
+
let { message, title, options } = model.value.control.delete.dialog;
|
|
365
|
+
ElMessageBox.confirm(message, title, options).then(() => {
|
|
366
|
+
emits("delete", { row, column, $index }, (res) => {
|
|
367
|
+
if (res) {
|
|
368
|
+
model.value.table.data.splice($index, 1);
|
|
369
|
+
model.value.table.page.total--;
|
|
370
|
+
}
|
|
371
|
+
})
|
|
372
|
+
}).catch(() => { });
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
//编辑方法
|
|
377
|
+
const editRow = (row, column, $index, m) => {
|
|
378
|
+
if (model.value.control.edit?.click) {
|
|
379
|
+
model.value.control.edit.click(row, column, $index, m);
|
|
380
|
+
} else {
|
|
381
|
+
model.value.form.disabled = false;
|
|
382
|
+
model.value.dialog.mode = model.value.control.edit.mode;
|
|
383
|
+
model.value.dialog.title = model.value.control.edit.label;
|
|
384
|
+
emits("edit", row, column, $index, m);
|
|
385
|
+
Object.keys(row).forEach(key => {
|
|
386
|
+
if (model.value[key]) {
|
|
387
|
+
model.value[key].value = row[key];
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
dialogVisible.value = true;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
//查看方法
|
|
395
|
+
const readForm = (row, column, $index, m) => {
|
|
396
|
+
if (model.value.control.view?.click) {
|
|
397
|
+
model.value.control.view.click(row, column, $index, m);
|
|
398
|
+
} else {
|
|
399
|
+
model.value.form.disabled = true;
|
|
400
|
+
model.value.dialog.mode = model.value.control.view.mode;
|
|
401
|
+
model.value.dialog.title = model.value.control.view.label;
|
|
402
|
+
emits("view", row, column, $index, m);
|
|
403
|
+
Object.keys(row).forEach(key => {
|
|
404
|
+
if (model.value[key]) {
|
|
405
|
+
model.value[key].value = row[key];
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
dialogVisible.value = true;
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
//提交方法
|
|
413
|
+
const submit = (formInfo, model) => {
|
|
414
|
+
emits("submit", formInfo, model, (res) => {
|
|
415
|
+
if (res) {
|
|
416
|
+
dialogVisible.value = false;
|
|
417
|
+
}
|
|
418
|
+
})
|
|
419
|
+
}
|
|
420
|
+
//重置方法
|
|
421
|
+
const formReset = (callback) => {
|
|
422
|
+
emits("reset", callback)
|
|
423
|
+
}
|
|
378
424
|
|
|
379
|
-
|
|
425
|
+
//表格列
|
|
380
426
|
const tableColumns = computed(() => Object.fromEntries(
|
|
381
427
|
Object.entries(model.value)
|
|
382
428
|
.filter(a => a[1].type != "hidden")
|
|
@@ -386,4 +432,21 @@ const tableColumns = computed(() => Object.fromEntries(
|
|
|
386
432
|
return [key[0], key[1]]
|
|
387
433
|
}).sort((a, b) => a[1].sort - b[1].sort))
|
|
388
434
|
);
|
|
389
|
-
|
|
435
|
+
|
|
436
|
+
//监听model变化,重新加载数据
|
|
437
|
+
watchEffect(() => {
|
|
438
|
+
model.value.table.load();
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
</script>
|
|
442
|
+
|
|
443
|
+
<style scoped>
|
|
444
|
+
.max {
|
|
445
|
+
cursor: pointer;
|
|
446
|
+
color: #333;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.max:hover {
|
|
450
|
+
color: var(--el-color-primary);
|
|
451
|
+
}
|
|
452
|
+
</style>
|