br-dionysus 1.16.5 → 1.16.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.md +22 -390
- package/attributes.json +1 -1
- package/dist/br-dionysus.es.js +4056 -4032
- package/dist/br-dionysus.umd.js +9 -9
- package/dist/index.css +1 -1
- package/dist/packages/MSelectTable/src/MSelectTable.vue.d.ts +4 -4
- package/dist/packages/MSelectTableV1/src/MSelectTableV1.vue.d.ts +1 -1
- package/dist/packages/MTable/src/MTable.vue.d.ts +1 -1
- package/dist/packages/MTableV2/src/MTableV2.vue.d.ts +19 -5
- package/dist/packages/Tool/slotsToData/slotsToData.d.ts +16 -4
- package/package.json +42 -42
- package/packages/MSelectTable/docs/DemoTest1.vue +92 -0
- package/packages/MSelectTable/docs/DemoTest2.vue +95 -0
- package/packages/MSelectTable/docs/DemoTest3.vue +113 -0
- package/packages/MSelectTable/docs/DemoTest4.vue +114 -0
- package/packages/MSelectTable/docs/demo.vue +11 -195
- package/packages/MSelectTable/src/MSelectTable.vue +97 -57
- package/packages/MTable/src/MTable.vue +5 -1
- package/packages/MTableV2/src/MTableV2.vue +19 -2
- package/packages/Tool/slotsToData/slotsToData.ts +27 -7
- package/tags.json +1 -1
- package/web-types.json +1 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<h5>多选,与外部设置绑定value</h5>
|
|
4
|
+
<p>选择器的值: {{ code }}</p>
|
|
5
|
+
<m-select-table
|
|
6
|
+
class="u-select"
|
|
7
|
+
v-model="code"
|
|
8
|
+
:tableTitle="commodityOptionsTitle"
|
|
9
|
+
:options="options"
|
|
10
|
+
:keywords="{ label: 'ApprovedQtyPU', value: 'DocNo' }"
|
|
11
|
+
:total="total"
|
|
12
|
+
scrollbarAlwaysOn
|
|
13
|
+
filterable
|
|
14
|
+
remote
|
|
15
|
+
multiple
|
|
16
|
+
border
|
|
17
|
+
:remoteMethod="remoteMethod"
|
|
18
|
+
@selected="selected"
|
|
19
|
+
@selectMultiple="selectMultiple"
|
|
20
|
+
@toPage="toPage"
|
|
21
|
+
></m-select-table>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup lang="ts">
|
|
26
|
+
import { ref, onMounted } from 'vue'
|
|
27
|
+
import { Page } from './../../typings/class'
|
|
28
|
+
|
|
29
|
+
const commodityOptionsTitle: TableTitle[] = [{
|
|
30
|
+
prop: 'PRDocType',
|
|
31
|
+
label: '单据类型'
|
|
32
|
+
}, {
|
|
33
|
+
prop: 'DocNo',
|
|
34
|
+
label: '请购单号'
|
|
35
|
+
}, {
|
|
36
|
+
prop: 'ApprovedQtyPU',
|
|
37
|
+
label: '名称'
|
|
38
|
+
|
|
39
|
+
}, {
|
|
40
|
+
prop: 'ACCode',
|
|
41
|
+
label: '货币'
|
|
42
|
+
}]
|
|
43
|
+
|
|
44
|
+
const code = ref<string | number | Array<string | number>>([])
|
|
45
|
+
|
|
46
|
+
const total = ref(0)
|
|
47
|
+
const options = ref<any[]>([])
|
|
48
|
+
const mockData: any[] = []
|
|
49
|
+
for (let i = 0; i < 1000; i++) {
|
|
50
|
+
mockData.push({
|
|
51
|
+
PRDocType: '测试数据' + (i + 1),
|
|
52
|
+
DocNo: i + 1,
|
|
53
|
+
ApprovedQtyPU: 'ApprovedQtyPU' + (i + 1),
|
|
54
|
+
ACCode: 'ACCode'
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
const getDataList = (page: Page = new Page(), str: string = '') => {
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
options.value = mockData.filter(item => item.PRDocType.includes(str)).slice(0, page.pageSize)
|
|
60
|
+
total.value = mockData.length
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
options.value = [{
|
|
66
|
+
PRDocType: 'xxxPRDocType1',
|
|
67
|
+
DocNo: 1,
|
|
68
|
+
ApprovedQtyPU: 'xxxApprovedQtyPU1',
|
|
69
|
+
ACCode: 'xxxACCode1'
|
|
70
|
+
}, {
|
|
71
|
+
PRDocType: 'xxxPRDocType2',
|
|
72
|
+
DocNo: 2,
|
|
73
|
+
ApprovedQtyPU: 'xxxApprovedQtyPU2',
|
|
74
|
+
ACCode: 'xxxACCode2'
|
|
75
|
+
}]
|
|
76
|
+
code.value = [1, 2]
|
|
77
|
+
}, 100)
|
|
78
|
+
|
|
79
|
+
const selected = (value: string | number | Array<number | string>) => {
|
|
80
|
+
console.log(value)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const toPage = (page: Page, str: any) => {
|
|
84
|
+
getDataList(page, str)
|
|
85
|
+
}
|
|
86
|
+
const selectMultiple = (value: string | number | Array<number | string>) => {
|
|
87
|
+
code.value = value
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const remoteMethod = async (query: string, page: Page = new Page()) => {
|
|
91
|
+
await getData(query, page)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const getData = async (query: string, page: any) => {
|
|
95
|
+
return new Promise<void>((resolve) => {
|
|
96
|
+
setTimeout(() => {
|
|
97
|
+
const start = (page.currentPage - 1) * page.pageSize
|
|
98
|
+
options.value = mockData.filter(item => item.PRDocType.includes(query)).slice(start, start + page.pageSize)
|
|
99
|
+
total.value = mockData.length
|
|
100
|
+
resolve()
|
|
101
|
+
}, 500)
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
onMounted(() => {
|
|
106
|
+
getDataList()
|
|
107
|
+
})
|
|
108
|
+
</script>
|
|
109
|
+
|
|
110
|
+
<style>
|
|
111
|
+
.u-select {
|
|
112
|
+
width: 240px;
|
|
113
|
+
}
|
|
114
|
+
</style>
|
|
@@ -1,205 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
:tableTitle="commodityOptionsTitle"
|
|
11
|
-
:options="options"
|
|
12
|
-
:keywords="{ label: 'ApprovedQtyPU', value: 'DocNo' }"
|
|
13
|
-
@selected="selected"
|
|
14
|
-
@selectMultiple="selectMultiple"
|
|
15
|
-
tableHeight="200"
|
|
16
|
-
@toPage="toPage"
|
|
17
|
-
:total="total"
|
|
18
|
-
scrollbarAlwaysOn
|
|
19
|
-
filterable
|
|
20
|
-
remote
|
|
21
|
-
multiple
|
|
22
|
-
allowCreate
|
|
23
|
-
border
|
|
24
|
-
@selectChange="selectChange"
|
|
25
|
-
:remoteMethod="remoteMethod"
|
|
26
|
-
>
|
|
27
|
-
<template #auxiliary>
|
|
28
|
-
辅助信息的插槽
|
|
29
|
-
</template>
|
|
30
|
-
</m-select-table>
|
|
31
|
-
<p>多选单绑定的value为字符串类型</p>
|
|
32
|
-
<p>第二个选择器的值: {{ code2 }}</p>
|
|
33
|
-
<m-select-table
|
|
34
|
-
class="u-select"
|
|
35
|
-
ref="selectRef"
|
|
36
|
-
v-model="code2"
|
|
37
|
-
:name="code2Name"
|
|
38
|
-
placeholder="请选择单号"
|
|
39
|
-
:tableTitle="commodityOptionsTitle"
|
|
40
|
-
:options="options"
|
|
41
|
-
:keywords="{ label: 'ApprovedQtyPU', value: 'DocNo' }"
|
|
42
|
-
@selected="selected"
|
|
43
|
-
@selectMultiple="selectMultiple"
|
|
44
|
-
tableHeight="200"
|
|
45
|
-
@toPage="toPage"
|
|
46
|
-
:total="total"
|
|
47
|
-
scrollbarAlwaysOn
|
|
48
|
-
filterable
|
|
49
|
-
remote
|
|
50
|
-
multiple
|
|
51
|
-
border
|
|
52
|
-
:remoteMethod="remoteMethod"
|
|
53
|
-
></m-select-table>
|
|
54
|
-
<p>单选</p>
|
|
55
|
-
<p>第三个择器的值: {{ code3 }}</p>
|
|
56
|
-
<m-select-table
|
|
57
|
-
class="u-select"
|
|
58
|
-
ref="selectRef"
|
|
59
|
-
v-model="code3"
|
|
60
|
-
placeholder="请选择单号"
|
|
61
|
-
:tableTitle="commodityOptionsTitle"
|
|
62
|
-
:options="options"
|
|
63
|
-
:keywords="{ label: 'ApprovedQtyPU', value: 'DocNo' }"
|
|
64
|
-
@selected="selected"
|
|
65
|
-
@selectMultiple="selectMultiple"
|
|
66
|
-
tableHeight="200"
|
|
67
|
-
@toPage="toPage"
|
|
68
|
-
:total="total"
|
|
69
|
-
scrollbarAlwaysOn
|
|
70
|
-
filterable
|
|
71
|
-
remote
|
|
72
|
-
allowCreate
|
|
73
|
-
:remoteMethod="remoteMethod"
|
|
74
|
-
:popupWidth="800"
|
|
75
|
-
></m-select-table>
|
|
76
|
-
<!--<el-select-->
|
|
77
|
-
<!-- v-model="code2"-->
|
|
78
|
-
<!-- multiple-->
|
|
79
|
-
<!-->-->
|
|
80
|
-
<!-- <el-option-->
|
|
81
|
-
<!-- v-for="item in options"-->
|
|
82
|
-
<!-- :key="item.DocNo"-->
|
|
83
|
-
<!-- :label="item.ApprovedQtyPU"-->
|
|
84
|
-
<!-- :value="item.DocNo"-->
|
|
85
|
-
<!-- ></el-option>-->
|
|
86
|
-
<!--</el-select>-->
|
|
3
|
+
<!--<DemoTest1></DemoTest1>-->
|
|
4
|
+
<el-divider />
|
|
5
|
+
<!--<DemoTest2></DemoTest2>-->
|
|
6
|
+
<!--<el-divider />-->
|
|
7
|
+
<!--<DemoTest3></DemoTest3>-->
|
|
8
|
+
<!--<el-divider />-->
|
|
9
|
+
<!--<DemoTest4></DemoTest4>-->
|
|
87
10
|
</div>
|
|
88
11
|
</template>
|
|
89
12
|
|
|
90
13
|
<script setup lang="ts">
|
|
91
|
-
import
|
|
92
|
-
import
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
prop: 'PRDocType',
|
|
96
|
-
label: '单据类型'
|
|
97
|
-
// minWidth: 200
|
|
98
|
-
}, {
|
|
99
|
-
prop: 'DocNo',
|
|
100
|
-
label: '请购单号'
|
|
101
|
-
// minWidth: 200
|
|
102
|
-
}, {
|
|
103
|
-
prop: 'ApprovedQtyPU',
|
|
104
|
-
// minWidth: 300,
|
|
105
|
-
label: '名称'
|
|
106
|
-
|
|
107
|
-
}, {
|
|
108
|
-
prop: 'ACCode',
|
|
109
|
-
label: '货币'
|
|
110
|
-
// minWidth: 200
|
|
111
|
-
}]
|
|
112
|
-
const selectRef: any = ref<HTMLElement | null>(null)
|
|
113
|
-
|
|
114
|
-
const code = ref<string | number | Array<string | number>>([])
|
|
115
|
-
const code2 = ref<string | number | Array<string | number>>('')
|
|
116
|
-
const code2Name = ref<string | number | Array<string | number>>([])
|
|
117
|
-
const code3 = ref<string | number | Array<string | number>>('')
|
|
118
|
-
|
|
119
|
-
const total = ref(0)
|
|
120
|
-
const options = ref<any[]>([])
|
|
121
|
-
const mockData: any[] = []
|
|
122
|
-
for (let i = 0; i < 1000; i++) {
|
|
123
|
-
mockData.push({
|
|
124
|
-
PRDocType: '测试数据' + (i + 1),
|
|
125
|
-
DocNo: i + 1,
|
|
126
|
-
ApprovedQtyPU: 'ApprovedQtyPU' + (i + 1),
|
|
127
|
-
ACCode: 'ACCode'
|
|
128
|
-
})
|
|
129
|
-
}
|
|
130
|
-
const getDataList = (page: Page = new Page(), str: string = '') => {
|
|
131
|
-
setTimeout(() => {
|
|
132
|
-
options.value = mockData.filter(item => item.PRDocType.includes(str)).slice(0, page.pageSize)
|
|
133
|
-
total.value = mockData.length
|
|
134
|
-
})
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
setTimeout(() => {
|
|
138
|
-
options.value = [{
|
|
139
|
-
PRDocType: 'xxxPRDocType1',
|
|
140
|
-
DocNo: 1,
|
|
141
|
-
ApprovedQtyPU: 'xxxApprovedQtyPU1',
|
|
142
|
-
ACCode: 'xxxACCode1'
|
|
143
|
-
}, {
|
|
144
|
-
PRDocType: 'xxxPRDocType2',
|
|
145
|
-
DocNo: 2,
|
|
146
|
-
ApprovedQtyPU: 'xxxApprovedQtyPU2',
|
|
147
|
-
ACCode: 'xxxACCode2'
|
|
148
|
-
}]
|
|
149
|
-
code.value = [1, 2]
|
|
150
|
-
code2.value = ''
|
|
151
|
-
code2Name.value = ['xxxApprovedQtyPU2', 'xxxApprovedQtyPU3', 'xxxApprovedQtyPU4']
|
|
152
|
-
code3.value = 1
|
|
153
|
-
|
|
154
|
-
// setTimeout(() => {
|
|
155
|
-
// options.value = []
|
|
156
|
-
// }, 2500)
|
|
157
|
-
}, 1000)
|
|
158
|
-
|
|
159
|
-
const selected = (value: string | number | Array<number | string>) => {
|
|
160
|
-
console.log(value)
|
|
161
|
-
// code.value = value
|
|
162
|
-
// console.log('selected',value)
|
|
163
|
-
// // console.log('selected', row)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const toPage = (page: Page, str: any) => {
|
|
167
|
-
getDataList(page, str)
|
|
168
|
-
}
|
|
169
|
-
const selectMultiple = (value: string | number | Array<number | string>) => {
|
|
170
|
-
code.value = value
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const remoteMethod = async (query: string, page: Page = new Page()) => {
|
|
174
|
-
await getData(query, page)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const selectChange = (value: string | number | Array<number | string>) => {
|
|
178
|
-
console.log(value)
|
|
179
|
-
}
|
|
180
|
-
const getData = async (query: string, page: any) => {
|
|
181
|
-
return new Promise<void>((resolve) => {
|
|
182
|
-
setTimeout(() => {
|
|
183
|
-
const start = (page.currentPage - 1) * page.pageSize
|
|
184
|
-
options.value = mockData.filter(item => item.PRDocType.includes(query)).slice(start, start + page.pageSize)
|
|
185
|
-
total.value = mockData.length
|
|
186
|
-
resolve()
|
|
187
|
-
}, 500)
|
|
188
|
-
})
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
onMounted(() => {
|
|
192
|
-
getDataList()
|
|
193
|
-
})
|
|
194
|
-
// const filterMethod = (searchValue: string, page: Page) => {
|
|
195
|
-
// // 手动过滤的得 保留一份原始数据
|
|
196
|
-
// const arr = JSON.parse(JSON.stringify(options.value))
|
|
197
|
-
// options.value = arr.filter((item: any) => item.ApprovedQtyPU.toString().includes(searchValue))
|
|
198
|
-
// }
|
|
14
|
+
// import DemoTest1 from 'packages/MSelectTable/docs/DemoTest1.vue'
|
|
15
|
+
// import DemoTest2 from 'packages/MSelectTable/docs/DemoTest2.vue'
|
|
16
|
+
// import DemoTest3 from 'packages/MSelectTable/docs/DemoTest3.vue'
|
|
17
|
+
// import DemoTest4 from 'packages/MSelectTable/docs/DemoTest4.vue'
|
|
199
18
|
</script>
|
|
200
19
|
|
|
201
20
|
<style>
|
|
202
|
-
.u-select {
|
|
203
|
-
width: 240px;
|
|
204
|
-
}
|
|
205
21
|
</style>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
@visibleChange="visibleChange"
|
|
19
19
|
@removeTag="removeTag"
|
|
20
20
|
@clear="clear"
|
|
21
|
-
@
|
|
21
|
+
@focus="focus"
|
|
22
22
|
@blur="changeBlur"
|
|
23
23
|
@change="change"
|
|
24
24
|
>
|
|
@@ -142,7 +142,8 @@ import {
|
|
|
142
142
|
ref,
|
|
143
143
|
watch,
|
|
144
144
|
reactive,
|
|
145
|
-
onMounted
|
|
145
|
+
onMounted,
|
|
146
|
+
nextTick
|
|
146
147
|
} from 'vue'
|
|
147
148
|
import { ElSelect, ElTable } from 'element-plus'
|
|
148
149
|
import { Page } from './../../typings/class'
|
|
@@ -259,18 +260,18 @@ const state = reactive<{
|
|
|
259
260
|
// 抛出事件
|
|
260
261
|
const emit = defineEmits<{
|
|
261
262
|
/** 单选或多选之后的回调 */
|
|
262
|
-
selected: [values: string | number | Array<string | number>, rows: Option[] | Option]
|
|
263
|
+
selected: [values: string | number | Array<string | number>, rows: Option[] | Option];
|
|
263
264
|
/** 多选确认按钮时的回调 配合isAffirmBtn使用 */
|
|
264
|
-
selectMultiple: [values: Array<string | number>, rows: Option[]]
|
|
265
|
+
selectMultiple: [values: Array<string | number>, rows: Option[]];
|
|
265
266
|
/** 当没有使用filterMethod时候才会有回调否则没有 */
|
|
266
|
-
toPage: [page: Page, query?: string]
|
|
267
|
-
/** 勾选数据change
|
|
268
|
-
selectChange: [values: string | number | Array<string | number>]
|
|
269
|
-
'update:modelValue': [value: string | number | Array<string | number>]
|
|
267
|
+
toPage: [page: Page, query?: string | number | Array<string | number>];
|
|
268
|
+
/** 勾选数据change事件,选中值不发生变化 */
|
|
269
|
+
selectChange: [values: string | number | Array<string | number>];
|
|
270
|
+
'update:modelValue': [value: string | number | Array<string | number>];
|
|
270
271
|
/** 用户点击清空按钮时触发 */
|
|
271
|
-
clear: []
|
|
272
|
-
/** 多选模式下移除tag时触发 */
|
|
273
|
-
removeTag: [tag: any]
|
|
272
|
+
clear: [];
|
|
273
|
+
/** 多选模式下移除tag时触发(标记,待处理) */
|
|
274
|
+
removeTag: [tag: any];
|
|
274
275
|
}>()
|
|
275
276
|
|
|
276
277
|
const allowCreateRow = computed(() => {
|
|
@@ -286,26 +287,32 @@ const allowCreateRow = computed(() => {
|
|
|
286
287
|
}))
|
|
287
288
|
})
|
|
288
289
|
|
|
289
|
-
const tabDataMap = ref<any[]>([])
|
|
290
|
-
watch(
|
|
291
|
-
|
|
292
|
-
|
|
290
|
+
const tabDataMap = ref<Record<string, any>[]>([])
|
|
291
|
+
watch(
|
|
292
|
+
() => state.tabData,
|
|
293
|
+
() => {
|
|
294
|
+
tabDataMap.value = [...state.tabData, ...allowCreateRow.value]
|
|
295
|
+
}
|
|
296
|
+
)
|
|
293
297
|
onMounted(() => {
|
|
294
298
|
tabDataMap.value = [...state.tabData, ...allowCreateRow.value]
|
|
295
299
|
})
|
|
296
|
-
watch(
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
300
|
+
watch(
|
|
301
|
+
() => allowCreateRow.value,
|
|
302
|
+
(val, oval) => {
|
|
303
|
+
const check = JSON.stringify(val) === JSON.stringify(oval)
|
|
304
|
+
if (check) return false
|
|
305
|
+
for (let i = 0; i < tabDataMap.value.length; i++) {
|
|
306
|
+
const item = tabDataMap.value[i]
|
|
307
|
+
if (!item.isAllowCreateRow) continue
|
|
308
|
+
i--
|
|
309
|
+
tabDataMap.value.splice(i, 1)
|
|
310
|
+
}
|
|
311
|
+
allowCreateRow.value.forEach(item => {
|
|
312
|
+
tabDataMap.value.push(item as any)
|
|
313
|
+
})
|
|
304
314
|
}
|
|
305
|
-
|
|
306
|
-
tabDataMap.value.push(item as any)
|
|
307
|
-
})
|
|
308
|
-
})
|
|
315
|
+
)
|
|
309
316
|
|
|
310
317
|
const upSelectModelValue = () => {
|
|
311
318
|
if (props.name || props.name === 0) return false
|
|
@@ -332,22 +339,18 @@ watch(
|
|
|
332
339
|
}
|
|
333
340
|
)
|
|
334
341
|
|
|
335
|
-
watch(
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
watch(
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
})
|
|
348
|
-
watch(() => modelValue.value, () => {
|
|
349
|
-
emit('update:modelValue', modelValue.value)
|
|
350
|
-
})
|
|
342
|
+
watch(
|
|
343
|
+
() => props.total,
|
|
344
|
+
() => {
|
|
345
|
+
page.total = props.total as number
|
|
346
|
+
}
|
|
347
|
+
)
|
|
348
|
+
watch(
|
|
349
|
+
() => modelValue.value,
|
|
350
|
+
() => {
|
|
351
|
+
emit('update:modelValue', modelValue.value)
|
|
352
|
+
}
|
|
353
|
+
)
|
|
351
354
|
|
|
352
355
|
// 点击行事件
|
|
353
356
|
const rowClick = (row: Option) => {
|
|
@@ -357,7 +360,11 @@ const rowClick = (row: Option) => {
|
|
|
357
360
|
modelValue.value = val[props.keywords.value]
|
|
358
361
|
blur()
|
|
359
362
|
|
|
360
|
-
emit('selected', val[props.keywords.value],
|
|
363
|
+
emit('selected', val[props.keywords.value], {
|
|
364
|
+
label: val[props.keywords.label],
|
|
365
|
+
value: val[props.keywords.value],
|
|
366
|
+
...val
|
|
367
|
+
})
|
|
361
368
|
}
|
|
362
369
|
|
|
363
370
|
// 确认的回调
|
|
@@ -374,8 +381,8 @@ const selectionChange = (selection: Option[]) => {
|
|
|
374
381
|
// 是否为删除
|
|
375
382
|
const isDelete = _value.some(item => !select.includes(item))
|
|
376
383
|
if (isDelete && !isVisible.value) return
|
|
377
|
-
modelValue.value = selection.map(
|
|
378
|
-
state.ids = selection.map(
|
|
384
|
+
modelValue.value = selection.map(item => item[props.keywords.value])
|
|
385
|
+
state.ids = selection.map(item => item[props.keywords.value])
|
|
379
386
|
state.selectRowS = selection
|
|
380
387
|
if (props.isAffirmBtn) return // 有确认按钮不走多选事件
|
|
381
388
|
emit('selected', state.ids as Array<string | number>, state.selectRowS)
|
|
@@ -399,28 +406,64 @@ const change = (value: string | number | Array<string | number>) => {
|
|
|
399
406
|
// emit('selectChange', modelValue.value)
|
|
400
407
|
}
|
|
401
408
|
|
|
402
|
-
//
|
|
409
|
+
// 是反填中状态
|
|
410
|
+
const isBackFill = ref<boolean>(false)
|
|
411
|
+
/** 默认反填(显示当前表格选中状态) */
|
|
403
412
|
const defaultBackFillValue = () => {
|
|
413
|
+
isBackFill.value = true
|
|
404
414
|
if (props.multiple) {
|
|
405
415
|
const modelArray: Array<string | number> = Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue]
|
|
406
416
|
const newArr = (state.tabData as Option[]).filter(item => modelArray.includes(item[props.keywords.value as keyof typeof item]))
|
|
407
|
-
|
|
417
|
+
nextTick(() => {
|
|
408
418
|
newArr.forEach((row) => {
|
|
409
419
|
const arr = state.tabData.filter(item => item[props.keywords.value] === row[props.keywords.value])
|
|
410
420
|
if (!arr.length) return false
|
|
411
421
|
selectTableRef.value.toggleRowSelection(arr[0], true)
|
|
412
422
|
})
|
|
423
|
+
isBackFill.value = false
|
|
413
424
|
})
|
|
414
425
|
} else {
|
|
415
426
|
const item = state.tabData.find(item => props.modelValue === item[props.keywords.value])
|
|
416
427
|
if (!item) return false
|
|
417
|
-
|
|
428
|
+
nextTick(() => {
|
|
418
429
|
selectTableRef.value.setCurrentRow(item, true)
|
|
430
|
+
isBackFill.value = false
|
|
419
431
|
})
|
|
420
|
-
modelValue.value = item[props.keywords.value]
|
|
421
432
|
}
|
|
422
433
|
}
|
|
423
|
-
|
|
434
|
+
/** 防抖 */
|
|
435
|
+
const debounce = (func: Function, wait: number) => {
|
|
436
|
+
let timeout: number | undefined
|
|
437
|
+
return (...args: any[]) => {
|
|
438
|
+
if (timeout !== undefined) {
|
|
439
|
+
clearTimeout(timeout)
|
|
440
|
+
}
|
|
441
|
+
timeout = window.setTimeout(() => {
|
|
442
|
+
func(...args)
|
|
443
|
+
}, wait)
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
const debounceDefaultBackFillValue = debounce(() => defaultBackFillValue(), 100)
|
|
447
|
+
watch(
|
|
448
|
+
() => props.options,
|
|
449
|
+
(val, oval) => {
|
|
450
|
+
if (!isVisible.value) return
|
|
451
|
+
const check = JSON.stringify(val) === JSON.stringify(oval)
|
|
452
|
+
if (check) return
|
|
453
|
+
state.tabData = val
|
|
454
|
+
debounceDefaultBackFillValue()
|
|
455
|
+
}, { deep: true }
|
|
456
|
+
)
|
|
457
|
+
watch(
|
|
458
|
+
() => props.modelValue,
|
|
459
|
+
(val) => {
|
|
460
|
+
if (!isVisible.value) return
|
|
461
|
+
if (!state.tabData.length || !val) return
|
|
462
|
+
debounceDefaultBackFillValue()
|
|
463
|
+
}
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
// 搜索过滤
|
|
424
467
|
const filterMethodHandle = (val: string) => {
|
|
425
468
|
state.searchValue = val.trim()
|
|
426
469
|
if (props.filterable && props.filterMethod) return props.filterMethod(val, page)
|
|
@@ -429,7 +472,8 @@ const filterMethodHandle = (val: string) => {
|
|
|
429
472
|
state.tabData = tableData.filter((item: Option) => item[props.keywords.label].toString().includes(val))
|
|
430
473
|
}
|
|
431
474
|
|
|
432
|
-
|
|
475
|
+
// 远程搜索
|
|
476
|
+
const remoteMethodHandle = (query: string = '') => {
|
|
433
477
|
state.searchValue = query.trim()
|
|
434
478
|
if (!props.remote) return false
|
|
435
479
|
|
|
@@ -514,6 +558,7 @@ defineExpose({ defaultBackFillValue, clear, focus })
|
|
|
514
558
|
|
|
515
559
|
.el-select-dropdown__empty {
|
|
516
560
|
padding: 0;
|
|
561
|
+
|
|
517
562
|
.head-box {
|
|
518
563
|
display: flex;
|
|
519
564
|
align-items: center;
|
|
@@ -524,12 +569,7 @@ defineExpose({ defaultBackFillValue, clear, focus })
|
|
|
524
569
|
.btn-box {
|
|
525
570
|
text-align: right;
|
|
526
571
|
margin-left: 5px;
|
|
527
|
-
// padding-bottom: 6px;
|
|
528
572
|
}
|
|
529
|
-
|
|
530
|
-
// .auxiliary-box {
|
|
531
|
-
// float: right;
|
|
532
|
-
// }
|
|
533
573
|
}
|
|
534
574
|
|
|
535
575
|
.m-table-select {
|
|
@@ -79,7 +79,11 @@ const slots = useSlots()
|
|
|
79
79
|
* 获取表格头信息
|
|
80
80
|
* */
|
|
81
81
|
const getTableTitle = (): TableTitle[] => {
|
|
82
|
-
const slotDefaultData = slotsToData(slots,
|
|
82
|
+
const slotDefaultData = slotsToData(slots, {
|
|
83
|
+
name: 'default',
|
|
84
|
+
isJumpFgt: false,
|
|
85
|
+
maxDepth: 1
|
|
86
|
+
})
|
|
83
87
|
const mTableColumnItemList: SlotsToDataReturnItem[] = []
|
|
84
88
|
slotDefaultData.forEach(item => {
|
|
85
89
|
if (item.children.length) {
|
|
@@ -22,8 +22,20 @@
|
|
|
22
22
|
:fixed="props.fixed"
|
|
23
23
|
:estimatedRowHeight="estimatedRowHeight"
|
|
24
24
|
:headerHeight="headerHeight"
|
|
25
|
+
:expandColumnKey="props.expandColumnKey"
|
|
25
26
|
v-bind="$attrs"
|
|
26
27
|
>
|
|
28
|
+
<!-- 传递 row 插槽用于展开行 -->
|
|
29
|
+
<template
|
|
30
|
+
v-if="slots.row"
|
|
31
|
+
#row="slotProps"
|
|
32
|
+
>
|
|
33
|
+
<slot
|
|
34
|
+
name="row"
|
|
35
|
+
v-bind="slotProps"
|
|
36
|
+
/>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
27
39
|
<template
|
|
28
40
|
v-if="!slots.empty"
|
|
29
41
|
#empty
|
|
@@ -70,7 +82,9 @@ const props = withDefaults(defineProps<{
|
|
|
70
82
|
/** Header 的高度由height设置。 如果传入数组,它会使 header row 等于数组长度 */
|
|
71
83
|
headerHeight?: number | number[] | null,
|
|
72
84
|
/** 单元格宽度自适应 */
|
|
73
|
-
cellWidthAdaptive?: boolean
|
|
85
|
+
cellWidthAdaptive?: boolean,
|
|
86
|
+
/** 展开列的key */
|
|
87
|
+
expandColumnKey?: string
|
|
74
88
|
}>(), {
|
|
75
89
|
size: 'default',
|
|
76
90
|
data: () => [],
|
|
@@ -83,11 +97,14 @@ const props = withDefaults(defineProps<{
|
|
|
83
97
|
fixed: false,
|
|
84
98
|
estimatedRowHeight: null,
|
|
85
99
|
headerHeight: null,
|
|
86
|
-
cellWidthAdaptive: false
|
|
100
|
+
cellWidthAdaptive: false,
|
|
101
|
+
expandColumnKey: ''
|
|
87
102
|
})
|
|
88
103
|
|
|
89
104
|
const slots = useSlots()
|
|
90
105
|
|
|
106
|
+
// ... 其他代码保持不变
|
|
107
|
+
|
|
91
108
|
const sizeToHeight: { [key: string]: number } = {
|
|
92
109
|
small: 30,
|
|
93
110
|
default: 50,
|
|
@@ -10,24 +10,44 @@ export interface SlotsToDataReturnItem {
|
|
|
10
10
|
children: SlotsToDataReturnItem[];
|
|
11
11
|
}
|
|
12
12
|
export type SlotsToDataReturn = SlotsToDataReturnItem[]
|
|
13
|
+
interface SlotsToDataOptions {
|
|
14
|
+
/** 插槽名 */
|
|
15
|
+
name?: string;
|
|
16
|
+
/** 是否跳过v-for生成的注释节点 */
|
|
17
|
+
isJumpFgt?: boolean;
|
|
18
|
+
/** 递归最大深度 */
|
|
19
|
+
maxDepth?: number;
|
|
20
|
+
/** 递归数据 */
|
|
21
|
+
data?: SlotsToDataReturn;
|
|
22
|
+
}
|
|
13
23
|
/**
|
|
14
24
|
* @description vue3的slots转json
|
|
15
|
-
* @param slots
|
|
16
|
-
* @param
|
|
17
|
-
* @param name
|
|
25
|
+
* @param slots vue组件的slots
|
|
26
|
+
* @param options 配置项
|
|
27
|
+
* @param name 插槽名,默认default
|
|
28
|
+
* @param isJumpFgt 是否跳过v-for生成的注释节点,默认true
|
|
29
|
+
* @param maxDepth 递归最大深度,默认3
|
|
18
30
|
* @param data
|
|
19
31
|
* */
|
|
20
|
-
const slotsToData = (
|
|
21
|
-
|
|
32
|
+
const slotsToData = (
|
|
33
|
+
slots: Slots,
|
|
34
|
+
{ name, isJumpFgt, maxDepth }: SlotsToDataOptions = { name: 'default', isJumpFgt: true, maxDepth: 3 },
|
|
35
|
+
data: SlotsToDataReturn = []
|
|
36
|
+
): SlotsToDataReturn => {
|
|
37
|
+
const _name = name || 'default'
|
|
38
|
+
const _isJumpFgt = isJumpFgt ?? true
|
|
39
|
+
const _maxDepth = maxDepth ?? 3
|
|
40
|
+
const slotsObj = slots[_name as keyof typeof slots] as Function | undefined
|
|
41
|
+
|
|
22
42
|
const slotsData: any[] = slotsObj ? slotsObj() : slots
|
|
23
43
|
for (let i = 0; i < slotsData.length; i++) {
|
|
24
44
|
const item = slotsData[i]
|
|
25
45
|
|
|
26
|
-
if (!item.type || (typeof item.type === 'symbol' &&
|
|
46
|
+
if (!item.type || (typeof item.type === 'symbol' && _isJumpFgt)) continue // 跳过注释节点
|
|
27
47
|
|
|
28
48
|
const children = item.children
|
|
29
49
|
const isChildren = Boolean(children)
|
|
30
|
-
const _data = isChildren ? slotsToData(children as any) : []
|
|
50
|
+
const _data = isChildren && _maxDepth > 1 ? slotsToData(children as any, { maxDepth: _maxDepth - 1 }) : []
|
|
31
51
|
|
|
32
52
|
data.push({
|
|
33
53
|
name: item.type.name,
|