vue-2024-ui 0.0.5 → 0.0.7
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 +283 -0
- package/README.md +218 -16
- package/README.table.md +58 -0
- package/package.json +1 -1
- package/src/components/g-form.vue +13 -5
- package/src/components/g-table.vue +32 -43
- package/src/components/index.d.ts +19 -0
- package/src/components/index.js +41 -2
package/README.form.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# form 表单 [表格](./README.table.md)
|
|
2
|
+
|
|
3
|
+
## FORM API 文档说明
|
|
4
|
+
|
|
5
|
+
### 所有属性和方法都在element-plus FORM 基础上扩展,只显示增加的属性和方法,安装前必须安装element-plus,其他原有属性和方法请查询 [官方文档](https://element-plus.org/zh-CN/component/form.html)
|
|
6
|
+
|
|
7
|
+
## form 表单新增属性
|
|
8
|
+
|
|
9
|
+
| 属性 | 说明 | 类型 | 默认值 |
|
|
10
|
+
| --------- | ------------------------------------------------------------------- | ------ | -------------------------------------------------------------------------------------------- |
|
|
11
|
+
| columns | 表单列数 | number | 2 |
|
|
12
|
+
| footer | 控制表单底部按钮是否显示和样式设置,hidden默认是false,style控制样式 | object | ```{hidden: false, style:{ display:"flex","align-items":"center",justifyContent:"center"}``` |
|
|
13
|
+
| submit | 表单提交按钮,增加了submitText,hidden 属性和submit方法 | object | ``` {type: "primary",submitText: "提交",hidden: false,submit: async (model) => {...}, } ``` |
|
|
14
|
+
| reset | 表单重置按钮,增加了restText,hidden 属性和reset方法 | object | ``` {type: "primary",resetText: "重置",hidden: false,reset: () => {...}, } ``` |
|
|
15
|
+
| formItems | 通过style属性设置所有items的样式 | object | ``` style:{width:100%} ``` |
|
|
16
|
+
|
|
17
|
+
## form 增加的事件
|
|
18
|
+
|
|
19
|
+
| 事件名 | 说明 | 类型 | 参数 |
|
|
20
|
+
| ------ | ------------ | -------- | -------------------------------------------------------------------------------------- |
|
|
21
|
+
| submit | 表单提交事件 | function | formData:表单要提交的数据 |
|
|
22
|
+
| reset | 表单重置事件 | function | callback(isCustReset=false) 默认已处理了重置事件,如要重写事件则回调时传入true后再处理 |
|
|
23
|
+
|
|
24
|
+
## form 重写 slots 增加的插槽
|
|
25
|
+
|
|
26
|
+
| 插槽名 | 说明 |
|
|
27
|
+
| ------------ | ---------------------- |
|
|
28
|
+
| footer | 重写表单footer功能按钮 |
|
|
29
|
+
| footer-left | 表单左边增加按钮 |
|
|
30
|
+
| footer-right | 表单右边增加按钮 |
|
|
31
|
+
|
|
32
|
+
## formItem 重写 slots
|
|
33
|
+
|
|
34
|
+
| 插槽名 | 说明 |
|
|
35
|
+
| --------------------- | -------------------------------- |
|
|
36
|
+
| item.key | 重写表单项item |
|
|
37
|
+
| item.key-label | 重写表单项标题 |
|
|
38
|
+
| item.key-ctrl | 重写表单控件 |
|
|
39
|
+
| item.key-ctrl-options | 重写表单控件有options的字项items |
|
|
40
|
+
|
|
41
|
+
## formItem 验证 validate
|
|
42
|
+
|
|
43
|
+
| 属性名 | 说明 | 类型 |
|
|
44
|
+
| -------- | ---------------------------------------------------- | -------- |
|
|
45
|
+
| required | 必输字段 | boolean |
|
|
46
|
+
| max,min | 字符串验证最大长度和最小长度,数字验证最大值和最小值 | number |
|
|
47
|
+
| type | number,email,url 验证数字,邮箱,网址 | string |
|
|
48
|
+
| pattern | 正则验证 | regex |
|
|
49
|
+
| validate | 自定义验证 validate(rule, value, callback) | function |
|
|
50
|
+
|
|
51
|
+
## 示例
|
|
52
|
+
|
|
53
|
+
### html
|
|
54
|
+
|
|
55
|
+
``` html
|
|
56
|
+
<template>
|
|
57
|
+
<div>
|
|
58
|
+
<g-form v-model="formData">
|
|
59
|
+
<template #age-label="{ item, model, data }">
|
|
60
|
+
</template>
|
|
61
|
+
<template #age-ctrl-suffix> 岁 </template>
|
|
62
|
+
<template #birthday-ctrl-default="cell">
|
|
63
|
+
{{ cell.data.data.text + "-" }}
|
|
64
|
+
</template>
|
|
65
|
+
<template #email-ctrl-suffix="{ model }">
|
|
66
|
+
{{ model.email.label }}
|
|
67
|
+
</template>
|
|
68
|
+
|
|
69
|
+
<template #sex-ctrl="{ data }">
|
|
70
|
+
<el-radio-button :value="1">男</el-radio-button>
|
|
71
|
+
<el-radio-button :value="2">女</el-radio-button>
|
|
72
|
+
</template>
|
|
73
|
+
<template #isDisabled-ctrl="{ data }">
|
|
74
|
+
{{ data.data.value }}
|
|
75
|
+
</template>
|
|
76
|
+
<template #hobby-ctrl="{ data }">
|
|
77
|
+
<el-checkbox-button :value="1">画画</el-checkbox-button>
|
|
78
|
+
<el-checkbox-button :value="2">游戏</el-checkbox-button>
|
|
79
|
+
</template>
|
|
80
|
+
<template #switch-ctrl-active-action>
|
|
81
|
+
<span class="custom-active-action">T</span>
|
|
82
|
+
</template>
|
|
83
|
+
<template #switch-ctrl-inactive-action>
|
|
84
|
+
<span class="custom-inactive-action">F</span>
|
|
85
|
+
</template>
|
|
86
|
+
<template #select-ctrl-empty="{ data }">
|
|
87
|
+
<el-button type="primary" size="small">增加</el-button>
|
|
88
|
+
</template>
|
|
89
|
+
<template #select2-ctrl-options="{ data }">111 </template>
|
|
90
|
+
<template #select-ctrl-options="{ data }">
|
|
91
|
+
<el-option :label="data.option.label" :value="data.option.value">
|
|
92
|
+
<div style="display: flex;color:#666;border:1px solid #ccc;width:300px;align-items: center;padding:5px;">
|
|
93
|
+
<b>》》</b>
|
|
94
|
+
<span style="display: flex;align-items: center; padding:3px 10px;height: 100%;">{{
|
|
95
|
+
data.option.label
|
|
96
|
+
}}</span>
|
|
97
|
+
</div>
|
|
98
|
+
</el-option>
|
|
99
|
+
</template>
|
|
100
|
+
<template #autoComplete-ctrl-default="{ data }">
|
|
101
|
+
{{ data.data.item.value + '--' + data.data.item.label }}
|
|
102
|
+
</template>
|
|
103
|
+
<template #autoComplete-ctrl-suffix="{ data }">
|
|
104
|
+
auto
|
|
105
|
+
</template>
|
|
106
|
+
<template #autoComplete-ctrl-prefix="{ data }">
|
|
107
|
+
P
|
|
108
|
+
</template>
|
|
109
|
+
<template #transfer-ctrl-default="{ data }">
|
|
110
|
+
{{ data.data.option.label }}
|
|
111
|
+
</template>
|
|
112
|
+
<template #upload-ctrl-default="{ data }">
|
|
113
|
+
<el-button style="width:100px">+</el-button>
|
|
114
|
+
</template>
|
|
115
|
+
<template #footer-left>
|
|
116
|
+
<el-button plain type="info" @click="formData.form.inline = false; formData.form.columns = 1">inline</el-button>
|
|
117
|
+
<el-button plain type="info" @click="formData.form.inline = true; formData.form.columns = 1">一倍</el-button>
|
|
118
|
+
<el-button plain type="success" @click="formData.form.inline = true; formData.form.columns = 2">二倍</el-button>
|
|
119
|
+
</template>
|
|
120
|
+
<template #footer-right v-if="formData.form.columns !== 1">
|
|
121
|
+
<el-button plain type="warning" @click="formData.form.inline = true; formData.form.columns = 3">三倍</el-button>
|
|
122
|
+
<el-button plain type="danger" @click="formData.form.inline = true; formData.form.columns = 4">四倍</el-button>
|
|
123
|
+
</template>
|
|
124
|
+
</g-form>
|
|
125
|
+
</div>
|
|
126
|
+
</template>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### javascript
|
|
130
|
+
|
|
131
|
+
``` javascript
|
|
132
|
+
|
|
133
|
+
<script setup>
|
|
134
|
+
import { ref ,reactive} from "vue";
|
|
135
|
+
const formData=reactive({
|
|
136
|
+
form:{
|
|
137
|
+
submit: { hidden: false },
|
|
138
|
+
reset: { hidden: false },
|
|
139
|
+
rules: {
|
|
140
|
+
"email.value": [{ required: true, message: "邮箱不能为空" }, { type: "email", message: "邮箱格式不正确" }],
|
|
141
|
+
"url.value": [{ required: true, message: "官网地址不能为空" }, { type: "url", message: "URL格式不正确" }],
|
|
142
|
+
},
|
|
143
|
+
columns: 2,
|
|
144
|
+
style: { boxShadow: null ,margin:"10px"},
|
|
145
|
+
},
|
|
146
|
+
id: { label: "ID", type: "number", value: 1, disabled: true, edit: false },
|
|
147
|
+
name: {
|
|
148
|
+
label: "姓名", value: "张三", width: 100,
|
|
149
|
+
max: 5,// min: 2,
|
|
150
|
+
//required: true,
|
|
151
|
+
rules: [{ required: true, message: "行内姓名不能为空!" }],
|
|
152
|
+
columns: 2, "show-word-limit": true,
|
|
153
|
+
formItem: { style: { border: "0px solid #fff", padding: "0px" } },
|
|
154
|
+
formatter: (row, column, cellValue, index) => row.name, sortable: true,
|
|
155
|
+
decimals: 2,
|
|
156
|
+
// suffix: " ¥", prefix: '--', width: 150
|
|
157
|
+
},
|
|
158
|
+
age: { label: "年龄", type: "number", value: 18, min: 16, decimals: { num: 0, pad: true }, suffix: '岁', sortable: true },
|
|
159
|
+
email: { label: "邮箱", type: "email", value: "xg816620@163.com", width: 400 },
|
|
160
|
+
qq: { label: "QQ", type: "number", value: 123456789, edit: false },
|
|
161
|
+
url: {
|
|
162
|
+
label: "官网地址", type: "url", columns: 2, value: "https://www.baidu.com", width: 260, align: 'left'
|
|
163
|
+
},
|
|
164
|
+
address: {
|
|
165
|
+
label: "地址", columns: 2, type: "textarea", maxlength: 50, width: 120, value: "重庆巴南万达广场B座22楼1-8", required: true, validate: (rule, value, callback) => {
|
|
166
|
+
if (value.length > 50) {
|
|
167
|
+
callback("字符串长度不能超过20个");
|
|
168
|
+
} else {
|
|
169
|
+
callback();
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
formItem: { "label-position": "right" }, suffix: '#'
|
|
173
|
+
},
|
|
174
|
+
sex: {
|
|
175
|
+
label: "性别", type: "radio", value: 2, options: [
|
|
176
|
+
{ label: "男", value: 1, border: false },
|
|
177
|
+
{ label: "女", value: 2, border: false }]
|
|
178
|
+
},
|
|
179
|
+
select: {
|
|
180
|
+
label: "选择分组", type: "select", value: 2, filterable: true, remote: true,
|
|
181
|
+
change: (a) => { console.log(a); },
|
|
182
|
+
"remote-method": (query, callback) => {
|
|
183
|
+
new Promise((resolve, reject) => {
|
|
184
|
+
setTimeout(() => {
|
|
185
|
+
resolve([
|
|
186
|
+
{ label: "apple", value: 1 },
|
|
187
|
+
{ label: "xiaomi", value: 2 },
|
|
188
|
+
{ label: "huawei", value: 3 },
|
|
189
|
+
{ label: "oppo", value: 4, disabled: "disabled" }
|
|
190
|
+
].filter(a => a.label.includes(query)))
|
|
191
|
+
}, 1000);
|
|
192
|
+
}).then(a => {
|
|
193
|
+
callback(a)
|
|
194
|
+
})
|
|
195
|
+
},
|
|
196
|
+
options: [
|
|
197
|
+
{
|
|
198
|
+
label: "手机", options: [
|
|
199
|
+
{ label: "apple", value: 1 },
|
|
200
|
+
{ label: "xiaomi", value: 2 },
|
|
201
|
+
{ label: "huawei", value: 3 }
|
|
202
|
+
],
|
|
203
|
+
}, {
|
|
204
|
+
label: "电器", options: [
|
|
205
|
+
{ label: "电视", value: 4 },
|
|
206
|
+
{ label: "冰箱", value: 5 },
|
|
207
|
+
{ label: "空调", value: 6 }
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
select2: {
|
|
213
|
+
label: "选择", type: "select", value: 3, visible: false,
|
|
214
|
+
options: [
|
|
215
|
+
{ label: "apple", value: 1 },
|
|
216
|
+
{ label: "xiaomi", value: 2 },
|
|
217
|
+
{ label: "huawei", value: 3 }
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
birthday: {
|
|
221
|
+
label: "生日", type: "datetime", value: "1985-01-01", dateFormat: "YYYY年MM月DD日", width: 200,
|
|
222
|
+
//prefix: '日期',
|
|
223
|
+
suffix: '@',
|
|
224
|
+
style: { width: "100%" },
|
|
225
|
+
},
|
|
226
|
+
hobby: {
|
|
227
|
+
label: "爱好", columns: 2, type: "checkbox-group", value: [1, 2], options: [
|
|
228
|
+
{ label: "跑步", value: 1, border: false },
|
|
229
|
+
{ label: "乒乓球", value: 2, border: false },
|
|
230
|
+
{ label: "看书", value: 3, border: false },
|
|
231
|
+
{ label: "学习", value: 4, border: false },],
|
|
232
|
+
},
|
|
233
|
+
time: {
|
|
234
|
+
label: "时间", type: "time", value: new Date(1985, 1, 1, 18, 20, 33), dateFormat: "time",
|
|
235
|
+
//prefix: '日期',
|
|
236
|
+
suffix: '@', width: 150,
|
|
237
|
+
style: { width: "100%" },
|
|
238
|
+
},
|
|
239
|
+
timeSelect: { label: "下拉时间", type: "time-select", value: "08:30", dateFormat: "mm:ss" },
|
|
240
|
+
isDisabled: { label: "是否启用", type: "checkbox", value: "是", trueValue: "是", formatter: (row, column, cellValue, index) => row.isDisabled == 2 ? '是' : '否' },
|
|
241
|
+
rate: { label: "星级", type: "rate", value: 3, suffix: '星级' },
|
|
242
|
+
slider: { label: "进度", type: "slider", value: 0.3, style: { width: "90%" }, visible: false, },
|
|
243
|
+
switch: {
|
|
244
|
+
label: "开关", type: "switch", value: 3, inlinePrompt: true, visible: false,
|
|
245
|
+
activeText: "完整展示多个内容",
|
|
246
|
+
inactiveText: "多个内容"
|
|
247
|
+
},
|
|
248
|
+
autoComplete: {
|
|
249
|
+
label: "建议输入", type: "autocomplete", value: "李四", visible: false, fetchSuggestions: (a, b) =>
|
|
250
|
+
b([{ value: "三四", label: 1 }, { value: "张三", label: 2 }, { value: "三德子", label: 3 }, { value: "李四", label: 4 }]
|
|
251
|
+
.filter((c) => c.value.toString().includes(a))), onSelect: (a) => console.log(a)
|
|
252
|
+
},
|
|
253
|
+
cascader: {
|
|
254
|
+
label: "级联选择", type: "cascader", value: [1, 2, 3], visible: false, options: [
|
|
255
|
+
{ label: "父一", value: 1, children: [{ label: "父二", value: 2, children: [{ label: "父三", value: 3 }] }] },
|
|
256
|
+
{ label: "父四", value: 4 },
|
|
257
|
+
{ label: "父五", value: 5 },
|
|
258
|
+
]
|
|
259
|
+
},
|
|
260
|
+
transfer: {
|
|
261
|
+
label: "穿梭框", type: "hidden", columns: 4, value: [1, 2], titles: ['全部', "已选"], visible: false,
|
|
262
|
+
filterable: true, data: [
|
|
263
|
+
{ label: "选项一", key: 1 }, { label: "选项二", key: 2 }, { label: "选项三", key: 3 }, { label: "选项四", key: 4 },
|
|
264
|
+
{ label: "选项五", key: 5 }, { label: "选项六", key: 6 }, { label: "选项七", key: 7 }, { label: "选项八", key: 8 },
|
|
265
|
+
],
|
|
266
|
+
|
|
267
|
+
},
|
|
268
|
+
treeSelect: {
|
|
269
|
+
label: "树形选择", type: "tree-select", value: [1, 2, 3], visible: false,
|
|
270
|
+
"show-checkbox": true, data: [
|
|
271
|
+
{
|
|
272
|
+
label: "父一", value: 1, children: [
|
|
273
|
+
{ label: "父二", value: 2, children: [{ label: "父三", value: 3 }] }]
|
|
274
|
+
},
|
|
275
|
+
{ label: "父四", value: 4 },
|
|
276
|
+
{ label: "父五", value: 5 },
|
|
277
|
+
],
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
</script>
|
|
282
|
+
|
|
283
|
+
```
|
package/README.md
CHANGED
|
@@ -1,29 +1,231 @@
|
|
|
1
|
-
# vue-
|
|
1
|
+
# vue-2024-ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## vue + element-plus
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 安装
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
``` javascript
|
|
8
|
+
import { createApp } from 'vue'
|
|
9
|
+
import ElementPlus from 'element-plus'
|
|
10
|
+
import 'element-plus/dist/index.css'
|
|
11
|
+
import zhCn from 'element-plus/es/locale/lang/zh-cn'
|
|
12
|
+
import App from './App.vue'
|
|
13
|
+
import gyc from 'vue-2024-ui'
|
|
14
|
+
const app = createApp(App)
|
|
15
|
+
app.use(ElementPlus, {
|
|
16
|
+
locale: zhCn,
|
|
17
|
+
})
|
|
18
|
+
app.use(gyc)
|
|
19
|
+
app.mount('#app')
|
|
8
20
|
|
|
9
|
-
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
[表单](./README.form.md) [表格](./README.table.md)
|
|
10
24
|
|
|
11
|
-
|
|
25
|
+
## 快速上手
|
|
12
26
|
|
|
13
|
-
|
|
27
|
+
``` html
|
|
28
|
+
<template>
|
|
29
|
+
<div>
|
|
30
|
+
<g-table v-model="formData" @select-all="all" @load="load" @delete="del" @view="read">
|
|
31
|
+
</g-table>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
14
34
|
|
|
15
|
-
```sh
|
|
16
|
-
npm install
|
|
17
35
|
```
|
|
18
36
|
|
|
19
|
-
|
|
37
|
+
``` javascript
|
|
38
|
+
<script setup>
|
|
39
|
+
import { reactive } from "vue";
|
|
40
|
+
const formData = reactive({
|
|
41
|
+
id: { label: "ID", type: "number", value: 1, disabled: true, edit: false },
|
|
42
|
+
name: {
|
|
43
|
+
label: "姓名", value: "张三", width: 100,
|
|
44
|
+
max: 5,// min: 2,
|
|
45
|
+
//required: true,
|
|
46
|
+
rules: [{ required: true, message: "行内姓名不能为空!" }],
|
|
47
|
+
columns: 2, "show-word-limit": true,
|
|
48
|
+
formItem: { style: { border: "0px solid #fff", padding: "0px" } },
|
|
49
|
+
formatter: (row, column, cellValue, index) => row.name, sortable: true,
|
|
50
|
+
decimals: 2,
|
|
51
|
+
// suffix: " ¥", prefix: '--', width: 150
|
|
52
|
+
},
|
|
53
|
+
age: { label: "年龄", type: "number", value: 18, min: 16, decimals: { num: 0, pad: true }, suffix: '岁', sortable: true },
|
|
54
|
+
email: { label: "邮箱", type: "email", value: "xg816620@163.com", width: 400 },
|
|
55
|
+
qq: { label: "QQ", type: "number", value: 123456789, edit: false },
|
|
56
|
+
url: {
|
|
57
|
+
label: "官网地址", type: "url", columns: 2, value: "https://www.baidu.com", width: 260, align: 'left'
|
|
58
|
+
},
|
|
59
|
+
address: {
|
|
60
|
+
label: "地址", columns: 2, type: "textarea", maxlength: 50, width: 120, value: "重庆巴南万达广场B座22楼1-8", required: true, validate: (rule, value, callback) => {
|
|
61
|
+
if (value.length > 50) {
|
|
62
|
+
callback("字符串长度不能超过20个");
|
|
63
|
+
} else {
|
|
64
|
+
callback();
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
formItem: { "label-position": "right" }, suffix: '#'
|
|
68
|
+
},
|
|
69
|
+
sex: {
|
|
70
|
+
label: "性别", type: "radio", value: 2, options: [
|
|
71
|
+
{ label: "男", value: 1, border: false },
|
|
72
|
+
{ label: "女", value: 2, border: false }]
|
|
73
|
+
},
|
|
74
|
+
select: {
|
|
75
|
+
label: "选择分组", type: "select", value: 2, filterable: true, remote: true,
|
|
76
|
+
change: (a) => { console.log(a); },
|
|
77
|
+
"remote-method": (query, callback) => {
|
|
78
|
+
new Promise((resolve, reject) => {
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
resolve([
|
|
81
|
+
{ label: "apple", value: 1 },
|
|
82
|
+
{ label: "xiaomi", value: 2 },
|
|
83
|
+
{ label: "huawei", value: 3 },
|
|
84
|
+
{ label: "oppo", value: 4, disabled: "disabled" }
|
|
85
|
+
].filter(a => a.label.includes(query)))
|
|
86
|
+
}, 1000);
|
|
87
|
+
}).then(a => {
|
|
88
|
+
callback(a)
|
|
89
|
+
})
|
|
90
|
+
},
|
|
91
|
+
options: [
|
|
92
|
+
{
|
|
93
|
+
label: "手机", options: [
|
|
94
|
+
{ label: "apple", value: 1 },
|
|
95
|
+
{ label: "xiaomi", value: 2 },
|
|
96
|
+
{ label: "huawei", value: 3 }
|
|
97
|
+
],
|
|
98
|
+
}, {
|
|
99
|
+
label: "电器", options: [
|
|
100
|
+
{ label: "电视", value: 4 },
|
|
101
|
+
{ label: "冰箱", value: 5 },
|
|
102
|
+
{ label: "空调", value: 6 }
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
select2: {
|
|
108
|
+
label: "选择", type: "select", value: 3, visible: false,
|
|
109
|
+
options: [
|
|
110
|
+
{ label: "apple", value: 1 },
|
|
111
|
+
{ label: "xiaomi", value: 2 },
|
|
112
|
+
{ label: "huawei", value: 3 }
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
birthday: {
|
|
116
|
+
label: "生日", type: "datetime", value: "1985-01-01", dateFormat: "YYYY年MM月DD日", width: 200,
|
|
117
|
+
//prefix: '日期',
|
|
118
|
+
suffix: '@',
|
|
119
|
+
style: { width: "100%" },
|
|
120
|
+
},
|
|
121
|
+
hobby: {
|
|
122
|
+
label: "爱好", columns: 2, type: "checkbox-group", value: [1, 2], options: [
|
|
123
|
+
{ label: "跑步", value: 1, border: false },
|
|
124
|
+
{ label: "乒乓球", value: 2, border: false },
|
|
125
|
+
{ label: "看书", value: 3, border: false },
|
|
126
|
+
{ label: "学习", value: 4, border: false },],
|
|
127
|
+
},
|
|
128
|
+
time: {
|
|
129
|
+
label: "时间", type: "time", value: new Date(1985, 1, 1, 18, 20, 33), dateFormat: "time",
|
|
130
|
+
//prefix: '日期',
|
|
131
|
+
suffix: '@', width: 150,
|
|
132
|
+
style: { width: "100%" },
|
|
133
|
+
},
|
|
134
|
+
timeSelect: { label: "下拉时间", type: "time-select", value: "08:30", dateFormat: "mm:ss" },
|
|
135
|
+
isDisabled: { label: "是否启用", type: "checkbox", value: "是", trueValue: "是", formatter: (row, column, cellValue, index) => row.isDisabled == 2 ? '是' : '否' },
|
|
136
|
+
rate: { label: "星级", type: "rate", value: 3, suffix: '星级' },
|
|
137
|
+
slider: { label: "进度", type: "slider", value: 0.3, style: { width: "90%" }, visible: false, },
|
|
138
|
+
switch: {
|
|
139
|
+
label: "开关", type: "switch", value: 3, inlinePrompt: true, visible: false,
|
|
140
|
+
activeText: "完整展示多个内容",
|
|
141
|
+
inactiveText: "多个内容"
|
|
142
|
+
},
|
|
143
|
+
autoComplete: {
|
|
144
|
+
label: "建议输入", type: "autocomplete", value: "李四", visible: false, fetchSuggestions: (a, b) =>
|
|
145
|
+
b([{ value: "三四", label: 1 }, { value: "张三", label: 2 }, { value: "三德子", label: 3 }, { value: "李四", label: 4 }]
|
|
146
|
+
.filter((c) => c.value.toString().includes(a))), onSelect: (a) => console.log(a)
|
|
147
|
+
},
|
|
148
|
+
cascader: {
|
|
149
|
+
label: "级联选择", type: "cascader", value: [1, 2, 3], visible: false, options: [
|
|
150
|
+
{ label: "父一", value: 1, children: [{ label: "父二", value: 2, children: [{ label: "父三", value: 3 }] }] },
|
|
151
|
+
{ label: "父四", value: 4 },
|
|
152
|
+
{ label: "父五", value: 5 },
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
transfer: {
|
|
156
|
+
label: "穿梭框", type: "hidden", columns: 4, value: [1, 2], titles: ['全部', "已选"], visible: false,
|
|
157
|
+
filterable: true, data: [
|
|
158
|
+
{ label: "选项一", key: 1 }, { label: "选项二", key: 2 }, { label: "选项三", key: 3 }, { label: "选项四", key: 4 },
|
|
159
|
+
{ label: "选项五", key: 5 }, { label: "选项六", key: 6 }, { label: "选项七", key: 7 }, { label: "选项八", key: 8 },
|
|
160
|
+
],
|
|
161
|
+
|
|
162
|
+
},
|
|
163
|
+
treeSelect: {
|
|
164
|
+
label: "树形选择", type: "tree-select", value: [1, 2, 3], visible: false,
|
|
165
|
+
"show-checkbox": true, data: [
|
|
166
|
+
{
|
|
167
|
+
label: "父一", value: 1, children: [
|
|
168
|
+
{ label: "父二", value: 2, children: [{ label: "父三", value: 3 }] }]
|
|
169
|
+
},
|
|
170
|
+
{ label: "父四", value: 4 },
|
|
171
|
+
{ label: "父五", value: 5 },
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
upload: {
|
|
175
|
+
label: "上传", type: "upload", value: [], style: { width: "100%" }, visible: false,
|
|
176
|
+
action: "https://jsonplaceholder.typicode.com/posts/",
|
|
177
|
+
headers: { "Authorization": "Bearer " + "your-token" }
|
|
178
|
+
},
|
|
179
|
+
control:{
|
|
180
|
+
view:{
|
|
181
|
+
auth:()=>true
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const createData = () => {
|
|
187
|
+
const list = [];
|
|
188
|
+
for (let i = 0; i < 210; i++) {
|
|
189
|
+
list.push({
|
|
190
|
+
id: i + 1,
|
|
191
|
+
name: `测试数据${i + 1}`,
|
|
192
|
+
age: Math.floor(Math.random() * 30) + 18,
|
|
193
|
+
email: `test${i + 1}@example.com`,
|
|
194
|
+
sex: (Math.floor(Math.random() * 2) + 1) == 2 ? '男' : '女',
|
|
195
|
+
select: 'xiaomi',
|
|
196
|
+
hobby: `测试数据${i + 1}`,
|
|
197
|
+
url: `https://www.example.com/test${i + 1}`,
|
|
198
|
+
birthday: new Date(2000, Math.floor(Math.random() * 12), Math.floor(Math.random() * 28) + 1),
|
|
199
|
+
address: `测试地址${i + 1}`,
|
|
200
|
+
rate: Math.floor(Math.random() * 5) + 1,
|
|
201
|
+
timeSelect: new Date(),
|
|
202
|
+
isDisabled: Math.floor(Math.random() * 2) + 1,
|
|
203
|
+
qq: "123"
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return list;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const del = (row, back) => {
|
|
210
|
+
back(true)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const edit = (row, c, i, m) => {
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
const read = (row, c, i, m) => {
|
|
217
|
+
}
|
|
218
|
+
formData.table = {
|
|
219
|
+
border: undefined,
|
|
220
|
+
page: { pageSize: 10, style: { justifyContent: 'flex-end' }, onChange: (a, b) => console.log(a, b) }
|
|
221
|
+
}
|
|
222
|
+
const all = (d) => console.log(d);
|
|
223
|
+
const load = (d, callback) => {
|
|
224
|
+
const { pageSize, currentPage } = d;
|
|
225
|
+
callback(createData().filter((item, index) => index >= (currentPage - 1) * pageSize && index < currentPage * pageSize), createData().length);
|
|
226
|
+
}
|
|
20
227
|
|
|
21
|
-
```sh
|
|
22
|
-
npm run dev
|
|
23
|
-
```
|
|
24
228
|
|
|
25
|
-
|
|
229
|
+
</script>
|
|
26
230
|
|
|
27
|
-
```sh
|
|
28
|
-
npm run build
|
|
29
231
|
```
|
package/README.table.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# table 表格
|
|
2
|
+
[表单](./README.form.md)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# API 说明
|
|
6
|
+
### 所有属性和方法都在element-plus 基础上扩展,只显示增加的属性和方法,安装前必须安装element-plus,其他原有属性和方法请查询 [官方文档](https://element-plus.org/zh-CN/component/table.html)
|
|
7
|
+
|
|
8
|
+
# table 表格新增属性
|
|
9
|
+
|
|
10
|
+
| 属性 | 说明 | 类型 | 默认值 |
|
|
11
|
+
| --------- | ------------------------------------------------------------------- | ------ | -------------------------------------------------------------------------------------------- |
|
|
12
|
+
| columns | 表单列数 | number | 2 |
|
|
13
|
+
| footer | 控制表单底部按钮是否显示和样式设置,hidden默认是false,style控制样式 | object | ```{hidden: false, style:{ display:"flex","align-items":"center",justifyContent:"center"}``` |
|
|
14
|
+
| submit | 表单提交按钮,增加了submitText,hidden 属性和submit方法 | object | ``` {type: "primary",submitText: "提交",hidden: false,submit: async (model) => {...}, } ``` |
|
|
15
|
+
| reset | 表单重置按钮,增加了restText,hidden 属性和reset方法 | object | ``` {type: "primary",resetText: "重置",hidden: false,reset: () => {...}, } ``` |
|
|
16
|
+
| formItems | 通过style属性设置所有items的样式 | object | ``` style:{width:100%} ``` |
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# table 增加的事件
|
|
20
|
+
|
|
21
|
+
| 事件名 | 说明 | 类型 | 参数 |
|
|
22
|
+
| ------ | ------------ | -------- | -------------------------------------------------------------------------------------- |
|
|
23
|
+
| submit | 表单提交事件 | function | formData:表单要提交的数据 |
|
|
24
|
+
| reset | 表单重置事件 | function | callback(isCustReset=false) 默认已处理了重置事件,如要重写事件则回调时传入true后再处理 |
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# table 重写 slots 增加的插槽
|
|
29
|
+
|
|
30
|
+
| 插槽名 | 说明 |
|
|
31
|
+
| ------------ | ---------------------- |
|
|
32
|
+
| footer | 重写表单footer功能按钮 |
|
|
33
|
+
| footer-left | 表单左边增加按钮 |
|
|
34
|
+
| footer-right | 表单右边增加按钮 |
|
|
35
|
+
|
|
36
|
+
# tablecolumn 重写 slots
|
|
37
|
+
|
|
38
|
+
| 插槽名 | 说明 |
|
|
39
|
+
| --------------------- | -------------------------------- |
|
|
40
|
+
| item.key | 重写表单项item |
|
|
41
|
+
| item.key-label | 重写表单项标题 |
|
|
42
|
+
| item.key-ctrl | 重写表单控件 |
|
|
43
|
+
| item.key-ctrl-options | 重写表单控件有options的字项items |
|
|
44
|
+
|
|
45
|
+
# 示例
|
|
46
|
+
### html
|
|
47
|
+
```
|
|
48
|
+
<template>
|
|
49
|
+
|
|
50
|
+
</template>
|
|
51
|
+
```
|
|
52
|
+
### javascript
|
|
53
|
+
```
|
|
54
|
+
<script setup>
|
|
55
|
+
|
|
56
|
+
</script>
|
|
57
|
+
```
|
|
58
|
+
|
package/package.json
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
</template>
|
|
37
37
|
|
|
38
38
|
<script setup>
|
|
39
|
-
import { computed, onMounted, ref, useAttrs, watch } from "vue";
|
|
39
|
+
import { computed, inject, onMounted, ref, useAttrs, watch } from "vue";
|
|
40
40
|
import gCtrl from "./g-ctrl.vue";
|
|
41
41
|
defineOptions({
|
|
42
42
|
name: "g-form",
|
|
@@ -47,6 +47,7 @@ const emits = defineEmits(["submit", "reset"]);
|
|
|
47
47
|
const gform = ref(null);
|
|
48
48
|
const columnsWidth = ref(0);
|
|
49
49
|
let marginRight = ref(32);
|
|
50
|
+
const options=inject('options');
|
|
50
51
|
//合并表单默认属性
|
|
51
52
|
model.value.form = {
|
|
52
53
|
inline: true,
|
|
@@ -56,6 +57,7 @@ model.value.form = {
|
|
|
56
57
|
"status-icon": true,
|
|
57
58
|
"scroll-into-view-options": true,
|
|
58
59
|
columns: 2,
|
|
60
|
+
...options?.form,
|
|
59
61
|
...model.value.form,
|
|
60
62
|
style: {
|
|
61
63
|
width: "600px",
|
|
@@ -65,15 +67,19 @@ model.value.form = {
|
|
|
65
67
|
paddingTop: "20px",
|
|
66
68
|
margin: "0px",
|
|
67
69
|
boxShadow: "0 0 5px rgba(0, 0, 0, 0.1)",
|
|
70
|
+
...options?.form?.style,
|
|
68
71
|
...model.value.form?.style,
|
|
69
72
|
...useAttrs().style
|
|
70
73
|
},
|
|
71
74
|
// 表单底部属性
|
|
72
75
|
footer: {
|
|
73
76
|
hidden: false,
|
|
77
|
+
...options?.form?.footer,
|
|
74
78
|
...model.value.form?.footer,
|
|
75
79
|
style: {
|
|
76
|
-
display: "flex", width: "100%", "align-items": "center", justifyContent: "center", margin: "5px",
|
|
80
|
+
display: "flex", width: "100%", "align-items": "center", justifyContent: "center", margin: "5px",
|
|
81
|
+
...options?.form?.footer?.style,
|
|
82
|
+
...model.value.form?.footer?.style
|
|
77
83
|
},
|
|
78
84
|
},
|
|
79
85
|
//表单提交按钮属性
|
|
@@ -83,8 +89,8 @@ model.value.form = {
|
|
|
83
89
|
submitText: "提交",
|
|
84
90
|
plain: true,
|
|
85
91
|
hidden: false,
|
|
92
|
+
...options?.form?.submit,
|
|
86
93
|
submit: async (model) => {
|
|
87
|
-
console.log(model);
|
|
88
94
|
if (!gform.value) return
|
|
89
95
|
await gform.value.validate((valid, fields) => {
|
|
90
96
|
if (valid) {
|
|
@@ -112,10 +118,12 @@ model.value.form = {
|
|
|
112
118
|
gform.value.resetFields();
|
|
113
119
|
}
|
|
114
120
|
},
|
|
121
|
+
...options?.form?.reset,
|
|
115
122
|
...model.value.form?.reset
|
|
116
123
|
},
|
|
117
124
|
dialog: {
|
|
118
125
|
width: 635,
|
|
126
|
+
...options?.form?.dialog,
|
|
119
127
|
...model.value.form?.dialog
|
|
120
128
|
}
|
|
121
129
|
};
|
|
@@ -124,6 +132,7 @@ model.value.formItems = {
|
|
|
124
132
|
type: "hidden",
|
|
125
133
|
style: {
|
|
126
134
|
width: "100%",
|
|
135
|
+
...options?.formItems?.style,
|
|
127
136
|
...model.value.formItems?.style
|
|
128
137
|
},
|
|
129
138
|
...model.value.formItems,
|
|
@@ -228,8 +237,7 @@ const load = () => {
|
|
|
228
237
|
else {
|
|
229
238
|
model.value.form.style.width = "600px";
|
|
230
239
|
}
|
|
231
|
-
model.value.form.dialog.width = +model.value?.form?.style?.width.replace("px", "")+35+"px";
|
|
232
|
-
console.log(model.value.form.dialog.width);
|
|
240
|
+
model.value.form.dialog.width = +model.value?.form?.style?.width.replace("px", "") + 35 + "px";
|
|
233
241
|
for (const [key, value] of Object.entries(items.value)) {
|
|
234
242
|
model.value[key].formItem = { ...model.value[key].formItem, ...value.formItem }
|
|
235
243
|
model.value[key].formItem.style = { ...model.value[key].formItem.style, ...value.formItem.style };
|
|
@@ -64,12 +64,10 @@
|
|
|
64
64
|
|
|
65
65
|
<script setup>
|
|
66
66
|
import dayjs from 'dayjs';
|
|
67
|
-
import ElementPlus from 'element-plus'
|
|
68
67
|
import { ElMessageBox } from 'element-plus';
|
|
69
|
-
import { computed, onMounted, reactive, watchEffect,
|
|
70
|
-
import { ElDialog } from 'element-plus';
|
|
71
|
-
//import gyc from "./index"
|
|
68
|
+
import { computed, onMounted, reactive, watchEffect, h ,inject} from 'vue';
|
|
72
69
|
import GForm from './g-form.vue';
|
|
70
|
+
import { openModal } from './index';
|
|
73
71
|
|
|
74
72
|
defineOptions({
|
|
75
73
|
name: "g-table",
|
|
@@ -78,6 +76,7 @@ defineOptions({
|
|
|
78
76
|
|
|
79
77
|
const emits = defineEmits(['load', 'view', "edit", "delete"]);
|
|
80
78
|
const model = defineModel({ required: true });
|
|
79
|
+
const options = inject('options');
|
|
81
80
|
|
|
82
81
|
//table default attrs
|
|
83
82
|
model.value.table = {
|
|
@@ -88,6 +87,7 @@ model.value.table = {
|
|
|
88
87
|
fit: false,
|
|
89
88
|
type: "hidden",
|
|
90
89
|
height: "calc(100vh - 55px)",
|
|
90
|
+
...options?.table,
|
|
91
91
|
...model.value.table,
|
|
92
92
|
load: () => {
|
|
93
93
|
let { currentPage, pageSize } = model.value.table.page;
|
|
@@ -103,6 +103,7 @@ model.value.table = {
|
|
|
103
103
|
currentPage: 1,
|
|
104
104
|
pageSizes: [5, 10, 20, 30, 40, 50],
|
|
105
105
|
layout: 'total, sizes, prev, pager, next, jumper',
|
|
106
|
+
...options?.table?.page,
|
|
106
107
|
...model.value.table?.page,
|
|
107
108
|
style: {
|
|
108
109
|
display: 'flex',
|
|
@@ -112,8 +113,21 @@ model.value.table = {
|
|
|
112
113
|
},
|
|
113
114
|
}
|
|
114
115
|
}
|
|
116
|
+
|
|
117
|
+
model.value.form = {
|
|
118
|
+
type: 'hidden',
|
|
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
|
+
}
|
|
115
129
|
model.value.control = {
|
|
116
|
-
type:
|
|
130
|
+
type: 'control', label: '操作', edit: false, width: 250, fixed: 'right',...options?.control, ...model.value?.control,
|
|
117
131
|
style: { ...model.value?.control?.style },
|
|
118
132
|
view: {
|
|
119
133
|
label: '查看', text: true, type: 'success',
|
|
@@ -123,8 +137,10 @@ model.value.control = {
|
|
|
123
137
|
view: (row, column, $index, m) => {
|
|
124
138
|
model.value.form.disabled = true;
|
|
125
139
|
emits("view", row, column, $index, m);
|
|
140
|
+
model.value.form.dialog.width = +(model.value?.form?.style?.width?.replace("px", "")) + 35 || 635;
|
|
126
141
|
openModal({
|
|
127
142
|
title: '查看',
|
|
143
|
+
width: model.value.form?.dialog?.width,
|
|
128
144
|
...model.value.form.dialog,
|
|
129
145
|
slots: {
|
|
130
146
|
// 自定义插槽内容
|
|
@@ -132,7 +148,9 @@ model.value.control = {
|
|
|
132
148
|
...model.value?.form?.dialog?.slots
|
|
133
149
|
},
|
|
134
150
|
});
|
|
135
|
-
},
|
|
151
|
+
},
|
|
152
|
+
...options?.control?.view,
|
|
153
|
+
...model.value?.control?.view
|
|
136
154
|
},
|
|
137
155
|
edit: {
|
|
138
156
|
label: '编辑', text: true, type: 'primary',
|
|
@@ -142,8 +160,10 @@ model.value.control = {
|
|
|
142
160
|
edit: (row, column, $index, m) => {
|
|
143
161
|
model.value.form.disabled = undefined;
|
|
144
162
|
emits("edit", row, column, $index, m);
|
|
163
|
+
model.value.form.dialog.width = +(model.value?.form?.style?.width?.replace("px", "")) + 35 || 635;
|
|
145
164
|
openModal({
|
|
146
165
|
title: '编辑',
|
|
166
|
+
width: model.value.form?.dialog?.width,
|
|
147
167
|
...model.value.form.dialog,
|
|
148
168
|
slots: {
|
|
149
169
|
// 自定义插槽内容
|
|
@@ -152,7 +172,9 @@ model.value.control = {
|
|
|
152
172
|
},
|
|
153
173
|
});
|
|
154
174
|
|
|
155
|
-
},
|
|
175
|
+
},
|
|
176
|
+
...options?.control?.edit,
|
|
177
|
+
...model.value?.control?.edit
|
|
156
178
|
},
|
|
157
179
|
delete: {
|
|
158
180
|
text: true, label: '删除', type: 'danger',
|
|
@@ -173,7 +195,9 @@ model.value.control = {
|
|
|
173
195
|
})
|
|
174
196
|
}).catch(() => { });
|
|
175
197
|
|
|
176
|
-
},
|
|
198
|
+
},
|
|
199
|
+
...options?.control?.delete,
|
|
200
|
+
...model.value?.control?.delete
|
|
177
201
|
},
|
|
178
202
|
};
|
|
179
203
|
|
|
@@ -184,41 +208,6 @@ const itemValue = reactive({
|
|
|
184
208
|
}
|
|
185
209
|
});
|
|
186
210
|
|
|
187
|
-
// 用 createApp 方法封装打开模态窗的方法
|
|
188
|
-
const openModal = (props = {}) => {
|
|
189
|
-
const el = document.createElement('div');
|
|
190
|
-
const app = createApp({
|
|
191
|
-
setup() {
|
|
192
|
-
const visible = ref(true);
|
|
193
|
-
const closeModal = () => {
|
|
194
|
-
visible.value = false;
|
|
195
|
-
app.unmount(); // 关闭对话框时卸载组件
|
|
196
|
-
delete el.remove(); // 关闭对话框时删除元素
|
|
197
|
-
};
|
|
198
|
-
return () => h(ElDialog, {
|
|
199
|
-
modelValue: visible.value,
|
|
200
|
-
'onUpdate:modelValue': closeModal,
|
|
201
|
-
draggable: true,
|
|
202
|
-
"append-to-body": true,
|
|
203
|
-
"v-if": visible.value,
|
|
204
|
-
width:model.value.form.dialog.width,
|
|
205
|
-
...props
|
|
206
|
-
},
|
|
207
|
-
() => [
|
|
208
|
-
props.slots.header ? h('div', { slot: 'header' }, props.slots.header()) : null,
|
|
209
|
-
// 传递名为 'default' 的插槽
|
|
210
|
-
props.slots.default ? h(props.slots.default()) : null,
|
|
211
|
-
// 传递名为 'footer' 的插槽
|
|
212
|
-
props.slots.footer ? h('div', { slot: 'footer' }, props.slots.footer()) : null,
|
|
213
|
-
// 可以继续添加其他插槽...
|
|
214
|
-
]
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
app.use(ElementPlus).mount(el);
|
|
219
|
-
document.body.appendChild(el);
|
|
220
|
-
};
|
|
221
|
-
|
|
222
211
|
//扩展formatter方法
|
|
223
212
|
const formatterExtends = (item, str) => {
|
|
224
213
|
let trueValue = str;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { App } from 'vue';
|
|
2
|
+
|
|
3
|
+
interface ModalProps {
|
|
4
|
+
slots: {
|
|
5
|
+
header?: () => JSX.Element;
|
|
6
|
+
default?: () => JSX.Element;
|
|
7
|
+
footer?: () => JSX.Element;
|
|
8
|
+
[key: string]: (() => JSX.Element) | undefined;
|
|
9
|
+
};
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare const _default: {
|
|
14
|
+
install(app: App, options?: any): void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default _default;
|
|
18
|
+
|
|
19
|
+
export declare const openModal: (props?: ModalProps, comType?: 'dialog' | 'drawer') => void;
|
package/src/components/index.js
CHANGED
|
@@ -1,10 +1,49 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import ElementPlus from 'element-plus'
|
|
4
|
+
import { ElDialog, ElDrawer } from "element-plus";
|
|
1
5
|
import gTable from "./g-table.vue";
|
|
2
6
|
import gForm from "./g-form.vue";
|
|
3
|
-
|
|
7
|
+
import { createApp, h, provide, reactive, readonly, ref } from "vue";
|
|
8
|
+
const goptions={};
|
|
4
9
|
|
|
5
10
|
export default {
|
|
6
|
-
install(app, options) {
|
|
11
|
+
install(app, options = {}) {
|
|
12
|
+
Object.assign(goptions, options);
|
|
7
13
|
app.component("g-table", gTable);
|
|
8
14
|
app.component("g-form", gForm);
|
|
15
|
+
app.provide("options", readonly(options));
|
|
9
16
|
}
|
|
10
17
|
}
|
|
18
|
+
const openModal = (props = {}, comType = "dialog") => {
|
|
19
|
+
const el = document.createElement('div');
|
|
20
|
+
const app = createApp({
|
|
21
|
+
setup() {
|
|
22
|
+
const visible = ref(true);
|
|
23
|
+
const closeModal = () => {
|
|
24
|
+
visible.value = false;
|
|
25
|
+
app.unmount(); // 关闭对话框时卸载组件
|
|
26
|
+
delete el.remove(); // 关闭对话框时删除元素
|
|
27
|
+
};
|
|
28
|
+
provide("options", goptions);
|
|
29
|
+
return () => h(comType == "dialog" ? ElDialog : comType == "drawer" ? ElDrawer : null, {
|
|
30
|
+
modelValue: visible.value,
|
|
31
|
+
'onUpdate:modelValue': closeModal,
|
|
32
|
+
draggable: true,
|
|
33
|
+
"append-to-body": true,
|
|
34
|
+
"v-if": visible.value,
|
|
35
|
+
...props
|
|
36
|
+
},
|
|
37
|
+
() => [
|
|
38
|
+
props.slots.header ? h('div', { slot: 'header' }, props.slots.header()) : null,
|
|
39
|
+
props.slots.default ? h(props.slots.default()) : null,
|
|
40
|
+
props.slots.footer ? h('div', { slot: 'footer' }, props.slots.footer()) : null,
|
|
41
|
+
]
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
app.use(ElementPlus).mount(el);
|
|
46
|
+
document.body.appendChild(el);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export { openModal };
|