vue-2024-ui 0.0.8 → 0.0.9

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 CHANGED
@@ -131,8 +131,8 @@
131
131
  ``` javascript
132
132
 
133
133
  <script setup>
134
- import { ref ,reactive} from "vue";
135
- const formData=reactive({
134
+ import { ref} from "vue";
135
+ const formData=ref({
136
136
  form:{
137
137
  submit: { hidden: false },
138
138
  reset: { hidden: false },
package/README.md CHANGED
@@ -36,8 +36,8 @@ app.mount('#app')
36
36
 
37
37
  ``` javascript
38
38
  <script setup>
39
- import { reactive } from "vue";
40
- const formData = reactive({
39
+ import { ref } from "vue";
40
+ const formData = ref({
41
41
  id: { label: "ID", type: "number", value: 1, disabled: true, edit: false },
42
42
  name: {
43
43
  label: "姓名", value: "张三", width: 100,
@@ -215,7 +215,7 @@ const edit = (row, c, i, m) => {
215
215
  }
216
216
  const read = (row, c, i, m) => {
217
217
  }
218
- formData.table = {
218
+ formData.value.table = {
219
219
  border: undefined,
220
220
  page: { pageSize: 10, style: { justifyContent: 'flex-end' }, onChange: (a, b) => console.log(a, b) }
221
221
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-2024-ui",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "src/components/index.js",
@@ -37,7 +37,8 @@
37
37
  </slot>
38
38
  </el-checkbox-group>
39
39
  <!--select-->
40
- <el-select v-model="ctrlValue" v-bind="selectModel" v-else-if="ctrlType == 'select'">
40
+ <el-select v-model="ctrlValue" :placeholder="itemInfo.label" v-bind="selectModel"
41
+ v-else-if="ctrlType == 'select'">
41
42
  <template #default v-if="itemInfo?.options?.some(a => a.options)">
42
43
  <slot :name="`${ctrlKey}-ctrl`" :options="itemInfo.options">
43
44
  <el-option-group v-for="group in itemInfo.options" :label="group.label">
@@ -61,24 +62,28 @@
61
62
  </template>
62
63
  </el-select>
63
64
  <!--tree-select-->
64
- <el-tree-select v-model="ctrlValue" v-bind="itemInfo" v-else-if="ctrlType == 'tree-select'">
65
+ <el-tree-select v-model="ctrlValue" :placeholder="itemInfo.label" v-bind="itemInfo"
66
+ v-else-if="ctrlType == 'tree-select'">
65
67
  <template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
66
68
  <slot :name="`${ctrlKey}-ctrl-${slot}`" :data></slot>
67
69
  </template>
68
70
  </el-tree-select>
69
71
  <!--time-->
70
- <el-time-picker v-model="ctrlValue" arrow-control v-bind="itemInfo" v-else-if="ctrlType == 'time'" />
72
+ <el-time-picker v-model="ctrlValue" arrow-control v-bind="itemInfo" :placeholder="itemInfo.label"
73
+ v-else-if="ctrlType == 'time'" />
71
74
  <!--time-select-->
72
- <el-time-select v-model="ctrlValue" start="06:30" step="00:15" end="23:30" v-bind="itemInfo"
73
- v-else-if="ctrlType == 'time-select'" />
75
+ <el-time-select v-model="ctrlValue" start="06:30" step="00:15" end="23:30" :placeholder="itemInfo.label"
76
+ v-bind="itemInfo" v-else-if="ctrlType == 'time-select'" />
74
77
  <!--date-->
75
- <el-date-picker v-model="ctrlValue" type="date" v-bind="itemInfo" v-else-if="ctrlType == 'date'">
78
+ <el-date-picker v-model="ctrlValue" type="date" :placeholder="itemInfo.label" v-bind="itemInfo"
79
+ v-else-if="ctrlType == 'date'">
76
80
  <template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
77
81
  <slot :name="`${ctrlKey}-ctrl-${slot}`" :data></slot>
78
82
  </template>
79
83
  </el-date-picker>
80
84
  <!--datetime-->
81
- <el-date-picker v-model="ctrlValue" type="datetime" v-bind="itemInfo" v-else-if="ctrlType == 'datetime'">
85
+ <el-date-picker v-model="ctrlValue" type="datetime" :placeholder="itemInfo.label" v-bind="itemInfo"
86
+ v-else-if="ctrlType == 'datetime'">
82
87
  <template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
83
88
  <slot :name="`${ctrlKey}-ctrl-${slot}`" :data></slot>
84
89
  </template>
@@ -114,20 +119,21 @@
114
119
  </template>
115
120
  </el-upload>
116
121
  <!--autocomplete-->
117
- <el-autocomplete v-model="ctrlValue" v-bind="itemInfo" v-else-if="ctrlType == 'autocomplete'">
122
+ <el-autocomplete v-model="ctrlValue" v-bind="itemInfo" :placeholder="itemInfo.label"
123
+ v-else-if="ctrlType == 'autocomplete'">
118
124
  <template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
119
125
  <slot :name="`${ctrlKey}-ctrl-${slot}`" :data></slot>
120
126
  </template>
121
127
  </el-autocomplete>
122
128
  <!--input-number-->
123
- <el-input-number v-model="ctrlValue" :min="0" :max="100000000" v-bind="itemInfo"
129
+ <el-input-number v-model="ctrlValue" :min="0" :max="100000000" :placeholder="itemInfo.label" v-bind="itemInfo"
124
130
  v-else-if="ctrlType == 'input-number'">
125
131
  <template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
126
132
  <slot :name="`${ctrlKey}-ctrl-${slot}`" :data></slot>
127
133
  </template>
128
134
  </el-input-number>
129
135
  <!--input-->
130
- <el-input v-model="ctrlValue" show-word-limit :maxlength="itemInfo.max || 25" :clearable="true"
136
+ <el-input v-model="ctrlValue" :placeholder="itemInfo.label" :maxlength="itemInfo.max || 25" :clearable="true"
131
137
  v-bind="itemInfo" v-else>
132
138
  <template v-for="(slot, index) in slots()" :key="index" #[slot]="data">
133
139
  <slot :name="`${ctrlKey}-ctrl-${slot}`" :data></slot>
@@ -139,8 +145,10 @@
139
145
  <script setup>
140
146
  defineOptions({ inheritAttrs: false });
141
147
  import { onMounted, useAttrs, useSlots } from "vue";
148
+ import { filterObject } from ".";
142
149
  const ctrlValue = defineModel({ required: true });
143
- const itemInfo = useAttrs().item;
150
+ const itemInfo = filterObject(useAttrs().item, k => k != 'value');
151
+ delete itemInfo.formatter;
144
152
  const ctrlKey = useAttrs().ctrlKey;
145
153
  const ctrlType = itemInfo.type;
146
154
  const model = useAttrs().model;
@@ -1,5 +1,7 @@
1
1
  <template>
2
- <el-form ref="gform" :model="model" v-bind="model.form" class="g-form-container">
2
+ <el-form ref="gform" :model="model"
3
+ v-bind="filterObject(model.form, k => !['columns', 'footer', 'submit', 'reset', 'slots', 'type', 'sort'].includes(k))"
4
+ class="g-form-container">
3
5
  <slot>
4
6
  <el-form-item :label="item.label" :prop="`${key}.value`" :rules="getItemRulesByItem(item)"
5
7
  v-for="(item, key) of items" :key="key" v-bind="{ ...model?.formItems, ...item?.formItem }"
@@ -18,11 +20,13 @@
18
20
  <slot name="footer" v-if="!model.form.footer.hidden">
19
21
  <div :style="model.form.footer.style">
20
22
  <slot name="footer-left"></slot>
21
- <el-button @click="model.form.submit.click(model)" v-bind="model.form.submit"
23
+ <el-button @click="model.form.submit.click(formInfo, model)"
24
+ v-bind="filterObject(model.form.submit, k => !['click'].includes(k))"
22
25
  v-if="!model?.form?.submit?.hidden">
23
26
  {{ model?.form?.submit?.label }}
24
27
  </el-button>
25
- <el-button @click="model.form.reset.click(model)" v-bind="model.form.reset"
28
+ <el-button @click="model.form.reset.click(model)"
29
+ v-bind="filterObject(model.form.reset, k => !['click'].includes(k))"
26
30
  v-if="!model?.form?.reset?.hidden">{{
27
31
  model?.form?.reset?.label
28
32
  }}</el-button>
@@ -34,15 +38,15 @@
34
38
  </template>
35
39
 
36
40
  <script setup>
37
- import { computed, inject, onMounted, ref, useAttrs, watch, watchEffect } from "vue";
41
+ import { computed, getCurrentInstance, inject, onBeforeUnmount, onMounted, ref, useAttrs, watch } from "vue";
38
42
  import gCtrl from "./g-ctrl.vue";
39
- import { convertToPx, mergeObjects } from "./index";
43
+ import { convertToPx, mergeObjects, filterObject } from "./index";
40
44
  defineOptions({
41
45
  name: "g-form",
42
46
  inheritAttrs: false
43
47
  })
44
48
  const model = defineModel({ required: true });
45
- const emits = defineEmits(["submit", "reset"]);
49
+ const emits = defineEmits(["usubmit", "reset"]);
46
50
  const gform = ref(null);
47
51
  let marginRight = ref(32);
48
52
  const options = inject('options');
@@ -73,13 +77,14 @@ const defaultFormAttrs = {
73
77
  label: "提交",
74
78
  plain: true,
75
79
  hidden: false,
76
- click: async (model) => {
80
+ click: async (formInfo, model) => {
81
+ emits("usubmit", formInfo, model);
77
82
  if (!gform.value) return
78
83
  await gform.value.validate((valid, fields) => {
79
84
  if (valid) {
80
- emits("submit", formInfo.value, model);
85
+ console.log("提交");
81
86
  } else {
82
- console.log('error submit!', fields);
87
+ console.log('表单验证不通过!', fields);
83
88
  }
84
89
  })
85
90
  },
@@ -101,6 +106,7 @@ const defaultFormAttrs = {
101
106
  }
102
107
  },
103
108
  },
109
+ slots: {}
104
110
  };
105
111
  model.value.form = mergeObjects(
106
112
  defaultFormAttrs,
@@ -204,7 +210,9 @@ const getItemRulesByItem = (item) => {
204
210
  return itemRules;
205
211
  }
206
212
 
207
- onMounted(() => { load(); })
213
+ onMounted(() => {
214
+ load();
215
+ })
208
216
 
209
217
  const load = () => {
210
218
  if (!model.value.form.inline) {
@@ -221,11 +229,14 @@ const load = () => {
221
229
  }
222
230
  };
223
231
 
232
+ onBeforeUnmount(() => {
233
+ console.log('destroy');
234
+ })
235
+
224
236
  watch(() => model.value.form.columns, () => load());
225
237
  watch(() => model.value.form.inline, () => load());
226
238
 
227
239
  const columnsWidth = computed(() => convertToPx(model.value.form.style.width) / model.value.form.columns);
228
- console.log(columnsWidth.value);
229
240
  //表单项
230
241
  const items = computed(() => Object.fromEntries(Object.entries(model.value)
231
242
  .filter(a => a[1].type != "hidden")
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <template v-for="(item, key) of getQueryModel(props.more)" :key="key">
3
+ <slot :name="`query-item-${key}`" :item :model>
4
+ <el-form-item :label="item.label" v-bind="{ ...model.queryItems, ...item?.search }">
5
+ <slot :name="'query-' + key" :item :model>
6
+ <g-ctrl v-model="queryModel[key]" :item :ctrlKey="key" :model>
7
+ <template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
8
+ <slot :name="slotKey" :data :item :model></slot>
9
+ </template>
10
+ </g-ctrl>
11
+ </slot>
12
+ <template #label>
13
+ <slot :name="'query-label-' + key" :item :model></slot>
14
+ </template>
15
+ </el-form-item>
16
+ </slot>
17
+ </template>
18
+ </template>
19
+
20
+ <script setup>
21
+ import gCtrl from './g-ctrl.vue';
22
+ import { computed, ref } from "vue";
23
+ const model = defineModel({ required: true });
24
+ const props = defineProps(["more"]);
25
+ const queryModel = defineModel("info", { required: true });
26
+ const getQueryModel = (flag) => computed(() =>
27
+ Object.fromEntries(Object.entries(model.value)
28
+ .filter(a => a[1].search && a[1].search.more === flag).map(key => [key[0], key[1]]))).value;
29
+ </script>
30
+
31
+ <style lang="scss" scoped></style>
@@ -0,0 +1,217 @@
1
+ <template>
2
+ <div class="g-query-container" style="position: relative;">
3
+ <el-form v-bind="filterObject(model.query, k => !['query', 'more', 'reset'].includes(k))">
4
+ <g-query-item v-model="model" v-model:info="queryModel" :more="undefined">
5
+ <template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
6
+ <slot :name="slotKey" :model></slot>
7
+ </template>
8
+ </g-query-item>
9
+ <el-form-item>
10
+ <el-button v-bind="model.query.query" @click="model.query.query.click()">
11
+ {{ model.query.query.label }}
12
+ </el-button>
13
+ <el-button v-bind="model.query.reset" @click="model.query.reset.click()">
14
+ {{ model.query.reset.label }}
15
+ </el-button>
16
+ <el-button v-bind="model.query.more" @click="model.query.more.click()"
17
+ v-if="model.query.more.mode !== 3">
18
+ {{ model.query.more.label }}
19
+ </el-button>
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">
23
+ {{ model.query.more.label }}
24
+ </el-button>
25
+ </template>
26
+ <template #default>
27
+ <el-form v-bind="filterObject(model.query, k => !['query', 'more', 'reset'].includes(k))">
28
+ <g-query-item v-model="model" v-model:info="queryModel" :more="true">
29
+ <template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
30
+ <slot :name="slotKey" :model></slot>
31
+ </template>
32
+ </g-query-item>
33
+ </el-form>
34
+ </template>
35
+ </el-popover>
36
+ <slot name="btns"></slot>
37
+ </el-form-item>
38
+ </el-form>
39
+ <Transition :duration="300" name="nested">
40
+ <div v-if="isShowMore && !model.query.more.hidden && model.query.more.mode == 1" class="outer">
41
+ <div class="inner">
42
+ <el-form v-bind="filterObject(model.query, k => !['query', 'more', 'reset'].includes(k))"
43
+ v-show="isShowMore" v-if="model.query.more.mode == 1">
44
+ <g-query-item v-model="model" v-model:info="queryModel" :more="true">
45
+ <template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
46
+ <slot :name="slotKey" :model></slot>
47
+ </template>
48
+ </g-query-item>
49
+ </el-form>
50
+ </div>
51
+ </div>
52
+ </Transition>
53
+ <el-drawer v-model="isShowMore" title="更多查询" :show-close="false" v-bind="model.query.more.dialog"
54
+ 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))">
56
+ <g-query-item v-model="model" v-model:info="queryModel" :more="true">
57
+ <template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
58
+ <slot :name="slotKey" :model></slot>
59
+ </template>
60
+ </g-query-item>
61
+ </el-form>
62
+ <template #footer v-if="!model.query.more.dialog.footer.hidden">
63
+ <div v-bind="model.query.more.dialog.footer">
64
+ <el-button v-bind="model.query.query" @click="model.query.query.click()">
65
+ {{ model.query.query.label }}
66
+ </el-button>
67
+ <el-button v-bind="model.query.reset" @click="model.query.reset.click()">
68
+ {{ model.query.reset.label }}
69
+ </el-button>
70
+ </div>
71
+ </template>
72
+ </el-drawer>
73
+ </div>
74
+ </template>
75
+
76
+ <script setup>
77
+ import { ref, inject } from 'vue'
78
+ import gQueryItem from './g-query-item.vue';
79
+ import { mergeObjects, filterObject } from './index';
80
+ const model = defineModel({ required: true });
81
+ const emits = defineEmits(['query', 'reset']);
82
+ const options = inject('options');
83
+ const isShowMore = ref(false);
84
+ let initValues = Object.fromEntries(Object.entries(model.value).filter(a => a[1].search).map(([key, val]) => [key, val.value]));
85
+ const queryModel = ref(initValues);
86
+ const defaultQueryAttrs = {
87
+ hidden: false,
88
+ type: "hidden",
89
+ labelWidth: 100,
90
+ inline: true,
91
+ style: { display: "flex", flex: 1, "flex-wrap": "wrap" },
92
+ more: {
93
+ mode: 2,
94
+ hidden: false,
95
+ type: "primary",
96
+ label: "更多",
97
+ click: () => {
98
+ isShowMore.value = !isShowMore.value;
99
+ },
100
+ },
101
+ reset: {
102
+ label: "重置",
103
+ type: "primary",
104
+ hidden: false,
105
+ plain: false,
106
+ click: () => {
107
+ queryModel.value = ref(initValues);
108
+ emits('reset', queryModel.value);
109
+ },
110
+ },
111
+ query: {
112
+ hidden: false,
113
+ type: "primary",
114
+ label: "查询",
115
+ click: () => {
116
+ emits('query', queryModel.value);
117
+ isShowMore.value = false;
118
+ }
119
+ }
120
+ }
121
+
122
+ // 查询表单属性
123
+ model.value.query = mergeObjects(defaultQueryAttrs, options?.query, model.value.query);
124
+
125
+ // 表单 查询更多 属性 drawer 方式2 和 popover 方式3
126
+ model.value.query.more.dialog = model.value.query.more.mode == 2 ? mergeObjects({
127
+ title: "更多查询", showClose: false, size: '30%', direction: "ttb", footer: {
128
+ hidden: false,
129
+ style: { textAlign: 'center' }
130
+ }
131
+ }, model.value.query.more.dialog) : model.value.query.more.mode == 3 ? mergeObjects({
132
+ placement: "top-start", title: "更多查询", width: 1200, trigger: "click"
133
+ }, model.value.query.more.dialog) : {};
134
+
135
+
136
+ // 表单查询项属性
137
+ const defaultQueryItemsAttrs = {
138
+ type: "hidden",
139
+ labelPosition: 'right',
140
+ style: {
141
+ width: "250px"
142
+ }
143
+ };
144
+ model.value.queryItems = mergeObjects(defaultQueryItemsAttrs, options?.queryItems, model.value.queryItems);
145
+
146
+ </script>
147
+
148
+ <style scoped>
149
+ .g-query-container {
150
+ display: flex;
151
+ flex: 1;
152
+ flex-direction: column;
153
+ padding: 10px;
154
+ box-sizing: border-box;
155
+ }
156
+
157
+ .outer {
158
+ /* position: absolute; */
159
+ min-height: 100px;
160
+ border-radius: 10px;
161
+ background-color: rgba(255, 255, 255, 0.8);
162
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
163
+ top: 60px;
164
+ padding: 10px;
165
+ width: 100%;
166
+ box-sizing: border-box;
167
+ }
168
+
169
+ .inner {
170
+ border-radius: 0;
171
+ min-height: 100px;
172
+ border: 1px solid #f2f2f2;
173
+ padding: 20px;
174
+ box-sizing: border-box;
175
+ width: 100%;
176
+ background-color: rgba(255, 255, 255, 1);
177
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
178
+ }
179
+
180
+ .nested-enter-active,
181
+ .nested-leave-active {
182
+ transition: all 0.3s ease-in-out;
183
+ }
184
+
185
+ /* delay leave of parent element */
186
+ .nested-leave-active {
187
+ transition-delay: 0.25s;
188
+ }
189
+
190
+ .nested-enter-from,
191
+ .nested-leave-to {
192
+ transform: translateY(-100px);
193
+ opacity: 0;
194
+ }
195
+
196
+ /* we can also transition nested elements using nested selectors */
197
+ .nested-enter-active .inner,
198
+ .nested-leave-active .inner {
199
+ transition: all 0.3s ease-in-out;
200
+ }
201
+
202
+ /* delay enter of nested element */
203
+ .nested-enter-active .inner {
204
+ transition-delay: 0.25s;
205
+ }
206
+
207
+ .nested-enter-from .inner,
208
+ .nested-leave-to .inner {
209
+ transform: translateY(-100px);
210
+ /*
211
+ Hack around a Chrome 96 bug in handling nested opacity transitions.
212
+ This is not needed in other browsers or Chrome 99+ where the bug
213
+ has been fixed.
214
+ */
215
+ opacity: 0.001;
216
+ }
217
+ </style>
@@ -1,8 +1,32 @@
1
1
  <template>
2
- <el-table class="g-table-container" v-bind="{ ...$attrs, ...model.table }">
2
+ <div class="table-query-container">
3
+ <slot name="query">
4
+ <g-query v-model="model" @query="query" @reset="reset">
5
+ <template v-for="(slot, slotKey, index) in $slots" :key="index" #[slotKey]="data">
6
+ <slot :name="slotKey" :model></slot>
7
+ </template>
8
+ <template #btns>
9
+ <slot name="btns">
10
+ <div class="btns" v-if="model.control.add.auth()">
11
+ <slot name="control-add-left"></slot>
12
+ <slot name="control-add">
13
+ <el-button v-bind="model.control.add" @click="model.control.add.click(model)">{{
14
+ model.control.add.label
15
+ }}</el-button>
16
+ </slot>
17
+ <slot name="control-add-right"></slot>
18
+ </div>
19
+ </slot>
20
+
21
+ </template>
22
+ </g-query>
23
+ </slot>
24
+
25
+ </div>
26
+ <el-table class="g-table-container" v-bind="{ ...$attrs, ...filterObject(model.table, k => k !== 'page') }">
3
27
  <slot>
4
28
  <el-table-column :prop="key" v-for="(value, key) of tableColumns" :key="key"
5
- v-bind="{ ...itemValue, ...value }" header-align="center">
29
+ v-bind="{ ...model.tableColumns, ...value }" header-align="center">
6
30
  <template #default="{ row, column, $index }"
7
31
  v-if="value.type != 'selection' && value.type != 'index' && value.type != 'expand'">
8
32
  <slot :name="`${key}`" :row :column :$index>
@@ -65,18 +89,21 @@
65
89
  <script setup>
66
90
  import dayjs from 'dayjs';
67
91
  import { ElMessageBox } from 'element-plus';
68
- import { computed, onMounted, ref, watchEffect, h, inject } from 'vue';
92
+ import { computed, onMounted, watchEffect, h, inject, ref, defineAsyncComponent, shallowRef } from 'vue';
69
93
  import GForm from './g-form.vue';
70
- import { openModal, mergeObjects,convertToPx } from './index';
94
+ import gQuery from './g-query.vue';
95
+ import { openModal, mergeObjects, convertToPx } from './index';
96
+ import { filterObject } from '.';
71
97
 
72
98
  defineOptions({
73
99
  name: "g-table",
74
100
  inheritAttrs: false
75
101
  })
76
102
 
77
- const emits = defineEmits(['load', 'view', "edit", "delete"]);
103
+ const emits = defineEmits(['load', 'view', "edit", "delete", 'add']);
78
104
  const model = defineModel({ required: true });
79
105
  const options = inject('options');
106
+ const queryInfo = ref({});
80
107
 
81
108
  //table default attrs
82
109
  const defaultTableAttrs = {
@@ -86,10 +113,10 @@ const defaultTableAttrs = {
86
113
  emptyText: '暂无数据',
87
114
  fit: false,
88
115
  type: "hidden",
89
- height: "calc(100vh - 55px)",
116
+ height: "calc(100vh - 65px)",
90
117
  load: () => {
91
118
  let { currentPage, pageSize } = model.value.table.page;
92
- emits('load', { currentPage, pageSize }, (data, total) => {
119
+ emits('load', { currentPage, pageSize, ...queryInfo.value }, (data, total) => {
93
120
  model.value.table.data = data;
94
121
  model.value.table.page.total = total;
95
122
  });
@@ -114,77 +141,104 @@ model.value.table = mergeObjects(
114
141
  model.value.table
115
142
  );
116
143
 
144
+ let closeModel = ref(() => { });
145
+ const editModel = defineAsyncComponent(() => import('./g-form.vue'));
117
146
  const defaultControl = {
118
147
  type: 'control', label: '操作', edit: false, width: 250, fixed: 'right',
119
148
  style: { ...model.value?.control?.style },
120
149
  add: {
121
150
  label: '新增', text: false, type: 'primary',
151
+ style: {
152
+ marginLeft: "10px",
153
+ },
122
154
  dialog: {
123
155
  title: '新增',
124
- popMode: "dialog",
156
+ mode: "drawer",
125
157
  slots: {
126
- default: () => h(GForm, { modelValue: model.value }),
158
+ default: () => h(GForm, { modelValue: model.value }, { ...model.value.form.slots }),
127
159
  },
128
160
  },
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 => {
161
+ auth: () => true,
162
+ click: (m) => {
163
+ model.value.form = {
164
+ ...model.value.form,
165
+ type: 'hidden',
166
+ disabled: undefined,
167
+ };
168
+ let w = model.value?.form?.style?.width || 600;
169
+ if (model.value.control.add.dialog.mode == "drawer") {
170
+ model.value.control.add.dialog.size = convertToPx(w) + 45;
171
+ } else {
172
+ model.value.control.add.dialog.width = convertToPx(w) + 35;
173
+ }
174
+ emits("add", m);
175
+ Object.keys(initFormData).forEach(key => {
136
176
  if (model.value[key]) {
137
- model.value[key].value = row[key];
177
+ model.value[key].value = initFormData[key];
138
178
  }
139
179
  });
140
- openModal(model.value.control.add.dialog, model.value?.control?.add?.dialog?.popMode);
180
+ model.value.form.close = openModal(model.value.control.add.dialog, model.value?.control?.add?.dialog?.mode);
141
181
  },
142
182
  },
143
183
  view: {
144
184
  label: '查看', text: true, type: 'success',
145
185
  dialog: {
146
186
  title: '查看',
147
- popMode: "dialog",
187
+ mode: "dialog",
148
188
  slots: {
149
- default: () => h(GForm, { modelValue: model.value }),
189
+ default: () => h(GForm, { modelValue: model.value }, { ...model.value.form.slots }),
150
190
  },
151
191
  },
152
192
  auth: (row, column, $index) => {
153
193
  return false;
154
194
  },
155
195
  click: (row, column, $index, m) => {
196
+ model.value.form = {
197
+ ...model.value.form,
198
+ type: 'hidden',
199
+ disabled: true,
200
+ };
156
201
  let w = model.value?.form?.style?.width || 600;
157
- if (model.value.control.view.dialog.popMode == "drawer") {
202
+ if (model.value.control.view.dialog.mode == "drawer") {
158
203
  model.value.control.view.dialog.size = convertToPx(w) + 45;
159
204
  } else {
160
205
  model.value.control.view.dialog.width = convertToPx(w) + 35;
161
206
  }
162
- model.value.form.disabled = true;
163
207
  emits("view", row, column, $index, m);
164
208
  Object.keys(row).forEach(key => {
165
209
  if (model.value[key]) {
166
210
  model.value[key].value = row[key];
167
211
  }
168
212
  });
169
- openModal(model.value.control.view.dialog, model.value?.control?.view?.dialog?.popMode);
213
+ model.value.form.close = openModal(model.value.control.view.dialog, model.value?.control?.view?.dialog?.mode);
170
214
  },
171
215
  },
172
216
  edit: {
173
217
  label: '编辑', text: true, type: 'primary',
174
218
  dialog: {
175
219
  title: '编辑',
176
- popMode: "dialog",
220
+ mode: "dialog",
177
221
  slots: {
178
- default: () => h(GForm, { modelValue: model.value }),
222
+ default: () => {
223
+ model.value.form.onUsubmit = () => {
224
+ if (closeModel.value)
225
+ closeModel.value();
226
+ }
227
+ return h(editModel, { modelValue: model.value, ...model.value.form }, { ...model.value.form.slots })
228
+ },
179
229
  },
180
230
  },
181
231
  auth: (row, column, $index) => {
182
232
  return true;
183
233
  },
184
234
  click: (row, column, $index, m) => {
185
- model.value.form.disabled = undefined;
235
+ model.value.form = {
236
+ ...model.value.form,
237
+ type: 'hidden',
238
+ disabled: undefined,
239
+ };
186
240
  let w = model.value?.form?.style?.width || 600;
187
- if (model.value.control.edit.dialog.popMode == "drawer") {
241
+ if (model.value.control.edit.dialog.mode == "drawer") {
188
242
  model.value.control.edit.dialog.size = convertToPx(w) + 45;
189
243
  } else {
190
244
  model.value.control.edit.dialog.width = convertToPx(w) + 35;
@@ -195,7 +249,7 @@ const defaultControl = {
195
249
  model.value[key].value = row[key];
196
250
  }
197
251
  });
198
- openModal(model.value?.control?.edit?.dialog, model.value?.control?.edit?.dialog?.popMode);
252
+ closeModel.value = openModal(model.value?.control?.edit?.dialog, model.value?.control?.edit?.dialog?.mode);
199
253
  },
200
254
  },
201
255
  delete: {
@@ -212,6 +266,7 @@ const defaultControl = {
212
266
  emits("delete", { row, column, $index }, (res) => {
213
267
  if (res) {
214
268
  model.value.table.data.splice($index, 1);
269
+ model.value.table.page.total--;
215
270
  }
216
271
  })
217
272
  }).catch(() => { });
@@ -226,12 +281,24 @@ model.value.control = mergeObjects(
226
281
  model.value?.control
227
282
  );
228
283
 
229
- //table column default attrs
230
- const itemValue = ref({
231
- width: 100, align: "center", formatter: (row, column, cellValue, index) => {
284
+ const defaultTableColumnsAttrs = {
285
+ type: "hidden",
286
+ width: 120,
287
+ align: "center",
288
+ formatter: (row, column, cellValue, index) => {
232
289
  return cellValue;
233
290
  }
234
- });
291
+ };
292
+
293
+ model.value.tableColumns = mergeObjects(
294
+ defaultTableColumnsAttrs,
295
+ options?.tableColumns,
296
+ model.value?.tableColumns
297
+ );
298
+
299
+ const initFormData = Object.fromEntries(Object.entries(filterObject(model.value, (k, val) => {
300
+ return (val.type != 'control' && val.edit !== false && val.type != 'hidden');
301
+ })).map(([key, val]) => [key, val.value]));
235
302
 
236
303
  //扩展formatter方法
237
304
  const formatterExtends = (item, str) => {
@@ -272,6 +339,17 @@ const formatterExtends = (item, str) => {
272
339
  return trueValue
273
340
  }
274
341
 
342
+ const reset = (q) => {
343
+ console.log(q);
344
+ queryInfo.value = q.value;
345
+ //model.value.table.load();
346
+ }
347
+
348
+ const query = (q) => {
349
+ queryInfo.value = q;
350
+ //model.value.table.load();
351
+ }
352
+
275
353
  onMounted(() => {
276
354
 
277
355
  });
@@ -290,6 +368,4 @@ const tableColumns = computed(() => Object.fromEntries(
290
368
  return [key[0], key[1]]
291
369
  }).sort((a, b) => a[1].sort - b[1].sort))
292
370
  );
293
- </script>
294
-
295
- <style lang="scss" scoped></style>
371
+ </script>
@@ -1,34 +1,37 @@
1
- import { App } from 'vue';
2
- import { Component } from 'vue';
3
- import { ElDialogProps, ElDrawerProps } from 'element-plus';
4
-
5
- declare module 'vue' {
6
- interface ComponentCustomProperties {
7
- openModel: typeof openModal;
8
- }
9
- }
1
+ import { Component, VNode } from 'vue';
2
+
3
+ declare const ElementPlus: any; // 假设ElementPlus已经有了类型声明
4
+ declare const ElDialog: Component;
5
+ declare const ElDrawer: Component;
10
6
 
11
7
  export interface GlobalOptions {
12
- // 在这里定义全局选项的类型
8
+ // 这里定义全局选项的类型
13
9
  }
14
10
 
15
11
  export interface OpenModalProps {
16
12
  slots?: {
17
- default?: () => any;
18
- header?: () => any;
19
- footer?: () => any;
13
+ default?: (a: any) => VNode;
14
+ header?: (p: any) => VNode;
15
+ footer?: (p: any) => VNode;
20
16
  };
21
- // 在这里定义其他传递给openModal函数的属性
17
+ // 其他props的类型定义
22
18
  }
23
19
 
24
- export function install(app: App, options?: GlobalOptions): void;
25
- export function openModal(props?: OpenModalProps, popMode?: 'dialog' | 'drawer'): void;
20
+ export function openModal(props?: OpenModalProps, mode?: 'dialog' | 'drawer'): () => void;
21
+
26
22
  export function convertToPx(value: string | number, referenceSize?: number): number;
27
- export function mergeObjects<T extends object>(...objects: T[]): T;
28
23
 
29
- declare const components: {
24
+ export function mergeObjects<T>(...objects: T[]): T;
25
+
26
+ export function filterObject<T>(obj: T, filter?: (key: keyof T) => boolean): T;
27
+
28
+ export const components: {
30
29
  gTable: Component;
31
30
  gForm: Component;
31
+ // 其他组件的类型定义
32
32
  };
33
33
 
34
- export default components;
34
+ declare const _default: {
35
+ install: (app: any, options?: GlobalOptions) => void;
36
+ };
37
+ export default _default;
@@ -22,18 +22,20 @@ export default {
22
22
  app.config.globalProperties.openModel = openModal;
23
23
  }
24
24
  }
25
- const openModal = (props = {}, popMode = "dialog") => {
25
+ const openModal = (props = {}, mode = "dialog") => {
26
26
  const el = document.createElement('div');
27
- const app = createApp({
27
+ let closeModal = () => { };
28
+ const visible = ref(true);
29
+ let modalApp = createApp({
28
30
  setup() {
29
- const visible = ref(true);
30
- const closeModal = () => {
31
+ closeModal = () => {
31
32
  visible.value = false;
32
- app.unmount(); // 关闭对话框时卸载组件
33
+ modalApp.unmount(); // 关闭对话框时卸载组件
33
34
  delete el.remove(); // 关闭对话框时删除元素
35
+ modalApp = null;
34
36
  };
35
37
  provide("options", globalOptions);
36
- return () => h(popMode == "dialog" ? ElDialog : popMode == "drawer" ? ElDrawer : null, {
38
+ return () => h(mode == "dialog" ? ElDialog : mode == "drawer" ? ElDrawer : null, {
37
39
  modelValue: visible.value,
38
40
  'onUpdate:modelValue': closeModal,
39
41
  draggable: true,
@@ -41,18 +43,19 @@ const openModal = (props = {}, popMode = "dialog") => {
41
43
  ...props
42
44
  },
43
45
  {
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
46
+ default: props.slots?.default ? (a) => h('div', {}, props.slots.default(a)) : null,
47
+ header: props.slots?.header ? (p) => h('div', {}, props.slots.header(p)) : null,
48
+ footer: props.slots?.footer ? (p) => h('div', {}, props.slots.footer(p)) : null
47
49
  }
48
50
  );
49
51
  }
50
52
  });
51
53
  for (const component of components) {
52
- app.component(component.name, component);
54
+ modalApp.component(component.name, component);
53
55
  }
54
- app.use(ElementPlus).mount(el);
56
+ modalApp.use(ElementPlus).mount(el);
55
57
  document.body.appendChild(el);
58
+ return closeModal;
56
59
  };
57
60
 
58
61
  function convertToPx(value, referenceSize = window.innerWidth) {
@@ -123,4 +126,18 @@ function mergeObjects(...objects) {
123
126
  }
124
127
  return result.value;
125
128
  }
126
- export { openModal, convertToPx, mergeObjects };
129
+
130
+
131
+ function filterObject(obj, filter = (key, value) => filter(key, value)) {
132
+ const result = {};
133
+ for (const key in obj) {
134
+ if (obj.hasOwnProperty(key)) {
135
+ if (filter(key, obj[key])) {
136
+ result[key] = obj[key];
137
+ }
138
+ }
139
+ }
140
+ return result;
141
+ }
142
+
143
+ export { openModal, convertToPx, mergeObjects, filterObject };