vue3-components-plus 3.0.10 → 3.0.12
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 +15 -2
- package/dist/ComponentDemo/ImageDemo.vue +2 -2
- package/dist/ComponentDemo/NsTableDemo/index.vue +516 -0
- package/dist/ComponentDemo/NsTableDemo/mockData.js +639 -0
- package/dist/cdn/ezuikit/ezuikit.js +27 -0
- package/dist/cdn/ezuikit/ezuikit_static/PlayCtrlWasm/playCtrl1/HasSIMD/Decoder.js +168 -0
- package/dist/cdn/ezuikit/ezuikit_static/PlayCtrlWasm/playCtrl1/NoSIMD/Decoder.js +168 -0
- package/dist/cdn/ezuikit/ezuikit_static/PlayCtrlWasm/playCtrl3/hasWorker/HasSIMD/Decoder.js +21 -0
- package/dist/cdn/ezuikit/ezuikit_static/PlayCtrlWasm/playCtrl3/hasWorker/HasSIMD/Decoder.wasm +0 -0
- package/dist/cdn/ezuikit/ezuikit_static/PlayCtrlWasm/playCtrl3/hasWorker/HasSIMD/Decoder.worker.js +1 -0
- package/dist/cdn/ezuikit/ezuikit_static/PlayCtrlWasm/playCtrl3/hasWorker/NoSIMD/Decoder.js +21 -0
- package/dist/cdn/ezuikit/ezuikit_static/PlayCtrlWasm/playCtrl3/hasWorker/NoSIMD/Decoder.wasm +0 -0
- package/dist/cdn/ezuikit/ezuikit_static/PlayCtrlWasm/playCtrl3/hasWorker/NoSIMD/Decoder.worker.js +1 -0
- package/dist/cdn/ezuikit/ezuikit_static/PlayCtrlWasm/playCtrl3/noWorker/Decoder.js +21 -0
- package/dist/cdn/ezuikit/ezuikit_static/PlayCtrlWasm/playCtrl3/noWorker/Decoder.wasm +0 -0
- package/dist/cdn/ezuikit/ezuikit_static/css/component.css +1257 -0
- package/dist/cdn/ezuikit/ezuikit_static/css/inspectTheme.css +354 -0
- package/dist/cdn/ezuikit/ezuikit_static/css/theme copy.css +126 -0
- package/dist/cdn/ezuikit/ezuikit_static/css/theme.css +140 -0
- package/dist/cdn/ezuikit/ezuikit_static/imgs/bg.png +0 -0
- package/dist/cdn/ezuikit/ezuikit_static/imgs/bg.svg +33 -0
- package/dist/cdn/ezuikit/ezuikit_static/imgs/empty.png +0 -0
- package/dist/cdn/ezuikit/ezuikit_static/imgs/end.png +0 -0
- package/dist/cdn/ezuikit/ezuikit_static/imgs/fallback.svg +52 -0
- package/dist/cdn/ezuikit/ezuikit_static/imgs/start.png +0 -0
- package/dist/cdn/ezuikit/ezuikit_static/rec/datepicker.js +1522 -0
- package/dist/cdn/ezuikit/ezuikit_static/rec/datepicker.min.css +36 -0
- package/dist/cdn/ezuikit/ezuikit_static/rec/datepicker.zh-CN.js +19 -0
- package/dist/cdn/ezuikit/ezuikit_static/rec/jquery.min.js +2 -0
- package/dist/cdn/ezuikit/ezuikit_static/speed/speed.css +145 -0
- package/dist/cdn/ezuikit/ezuikit_static/talk/adapeter.js +5497 -0
- package/dist/cdn/ezuikit/ezuikit_static/talk/janus.js +3507 -0
- package/dist/cdn/ezuikit/ezuikit_static/talk/tts-v4.js +343 -0
- package/dist/cdn/ezuikit.js +27 -0
- package/dist/cdn/h5player/h5player.min.js +313 -0
- package/dist/cdn/h5player/playctrl1/DecodeWorker.js +642 -0
- package/dist/cdn/h5player/playctrl1/Decoder.js +1 -0
- package/dist/cdn/h5player/playctrl1simd/DecodeWorker.js +642 -0
- package/dist/cdn/h5player/playctrl1simd/Decoder.js +1 -0
- package/dist/cdn/h5player/playctrl2/Decoder.js +21 -0
- package/dist/cdn/h5player/playctrl2/Decoder.wasm +0 -0
- package/dist/cdn/h5player/playctrl2/Decoder.worker.js +1 -0
- package/dist/cdn/h5player/playctrl3/Decoder.js +21 -0
- package/dist/cdn/h5player/playctrl3/Decoder.wasm +0 -0
- package/dist/cdn/h5player/playctrl3/Decoder.worker.js +1 -0
- package/dist/cdn/h5player/talk/AudioInterCom.js +21 -0
- package/dist/cdn/h5player/talk/AudioInterCom.wasm +0 -0
- package/dist/cdn/h5player/talkW/AudioInterCom.js +21 -0
- package/dist/cdn/h5player/talkW/AudioInterCom.wasm +0 -0
- package/dist/cdn/h5player/talkW/AudioInterCom.worker.js +1 -0
- package/dist/cdn/h5player/transform/libSystemTransform.js +6525 -0
- package/dist/cdn/h5player/transform/libSystemTransform.wasm +0 -0
- package/dist/cdn/h5player/transform/systemTransform-worker.js +120 -0
- package/dist/cdn/md5.js +254 -0
- package/dist/js/EasyPlayer-decode.js +1 -0
- package/dist/js/EasyPlayer-lib.js +1 -0
- package/dist/js/EasyPlayer-pro.js +1 -0
- package/dist/js/EasyPlayer-pro.wasm +0 -0
- package/dist/js/EasyPlayer-snap.wasm +0 -0
- package/dist/vue3-components-plus.css +1 -1
- package/dist/vue3-components-plus.js +8362 -6927
- package/dist/vue3-components-plus.umd.cjs +1 -1
- package/package.json +1 -2
- package/dist/cdn.zip +0 -0
- package/dist/js.zip +0 -0
package/README.md
CHANGED
|
@@ -1013,10 +1013,23 @@ autoScaleInit(document.querySelector('body'), {
|
|
|
1013
1013
|
|
|
1014
1014
|
## 更新日志
|
|
1015
1015
|
|
|
1016
|
+
```text
|
|
1017
|
+
version: 3.0.12
|
|
1018
|
+
日期: 2026-03-13
|
|
1019
|
+
更新内容:
|
|
1020
|
+
1. 添加NsTableContainer带搜索条件的表格
|
|
1021
|
+
```
|
|
1022
|
+
|
|
1023
|
+
```text
|
|
1024
|
+
version: 3.0.11
|
|
1025
|
+
日期: 2026-03-09
|
|
1026
|
+
更新内容:
|
|
1027
|
+
1. 修复bug
|
|
1028
|
+
```
|
|
1029
|
+
|
|
1016
1030
|
```text
|
|
1017
1031
|
version: 3.0.10
|
|
1018
1032
|
日期: 2026-01-23
|
|
1019
1033
|
更新内容:
|
|
1020
1034
|
1. 修改NsSaturationLine文字字体
|
|
1021
|
-
```
|
|
1022
|
-
|
|
1035
|
+
```
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
<script setup lang="ts">
|
|
12
12
|
import { reactive, ref } from 'vue';
|
|
13
|
-
import src from '@/assets/
|
|
14
|
-
import errorSrc from '@/assets/
|
|
13
|
+
import src from '@/assets/a.jpg'
|
|
14
|
+
import errorSrc from '@/assets/b.jpg'
|
|
15
15
|
const hasPreview = ref(true)
|
|
16
16
|
const apiUrl = reactive( {
|
|
17
17
|
type: Object,
|
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="demo-page">
|
|
3
|
+
<!-- 使用 NsTableContainer 组件 -->
|
|
4
|
+
<NsTableContainer
|
|
5
|
+
ref="containerRef"
|
|
6
|
+
:search-items="searchItems"
|
|
7
|
+
:external-search-params="externalSearchParams"
|
|
8
|
+
:search-props="{
|
|
9
|
+
labelWidth: '100px',
|
|
10
|
+
}"
|
|
11
|
+
:table-data="tableData"
|
|
12
|
+
:columns="columns"
|
|
13
|
+
:total="total"
|
|
14
|
+
:table-props="{
|
|
15
|
+
showSelection: true,
|
|
16
|
+
showIndex: true,
|
|
17
|
+
loading: loading,
|
|
18
|
+
rowKey: 'id',
|
|
19
|
+
showPagination: true,
|
|
20
|
+
}"
|
|
21
|
+
:load-data="loadData"
|
|
22
|
+
@search="handleSearch"
|
|
23
|
+
@reset="handleReset"
|
|
24
|
+
@add="handleAdd"
|
|
25
|
+
@selection-change="handleSelectionChange"
|
|
26
|
+
>
|
|
27
|
+
<!-- 自定义状态列 -->
|
|
28
|
+
<template #status="{ row }">
|
|
29
|
+
<el-tag :type="getStatusType(row.status)">
|
|
30
|
+
{{ getStatusText(row.status) }}
|
|
31
|
+
</el-tag>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<!-- 自定义性别列 -->
|
|
35
|
+
<template #gender="{ row }">
|
|
36
|
+
<el-tag :type="row.gender === 1 ? 'primary' : 'danger'" size="small">
|
|
37
|
+
{{ row.gender === 1 ? '男' : '女' }}
|
|
38
|
+
</el-tag>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<!-- 自定义部门列 -->
|
|
42
|
+
<template #department="{ row }">
|
|
43
|
+
<el-tag effect="plain">{{ getDepartmentText(row.department) }}</el-tag>
|
|
44
|
+
</template>
|
|
45
|
+
</NsTableContainer>
|
|
46
|
+
<!-- 选择操作区域 -->
|
|
47
|
+
<div class="selection-actions">
|
|
48
|
+
<el-button @click="getSelectedRows">获取选中行</el-button>
|
|
49
|
+
<el-button @click="getSelectedKeys">获取选中ID</el-button>
|
|
50
|
+
<el-button @click="selectRows([1, 3, 5])">选中ID为1,3,5的行</el-button>
|
|
51
|
+
<el-button @click="clearSelection">清空选择</el-button>
|
|
52
|
+
<el-button @click="selectAll">全选</el-button>
|
|
53
|
+
<el-button @click="checkSelection">检查选择状态</el-button>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<script setup lang="ts">
|
|
59
|
+
import { Delete, Edit, View } from '@element-plus/icons-vue'
|
|
60
|
+
import { ElDatePicker, ElInput, ElMessage, ElMessageBox, ElSelect, ElSwitch } from 'element-plus'
|
|
61
|
+
import { onMounted, ref } from 'vue'
|
|
62
|
+
import { fetchDepartmentOptions, fetchStatusOptions, filterUsers, mockUsers } from './mockData.js'
|
|
63
|
+
|
|
64
|
+
// ==================== 组件引用 ====================
|
|
65
|
+
const containerRef = ref(null)
|
|
66
|
+
|
|
67
|
+
// ==================== 搜索配置 ====================
|
|
68
|
+
// 当前搜索参数(从 PageSearch 获取)
|
|
69
|
+
const searchParams = ref({})
|
|
70
|
+
|
|
71
|
+
// 外部注入的搜索参数(用于特殊情况传参)
|
|
72
|
+
const externalSearchParams = ref({ test: 'aaa' })
|
|
73
|
+
|
|
74
|
+
// ==================== 数据状态 ====================
|
|
75
|
+
const loading = ref(false)
|
|
76
|
+
const tableData = ref([])
|
|
77
|
+
const total = ref(0)
|
|
78
|
+
|
|
79
|
+
const searchItems = ref([
|
|
80
|
+
{
|
|
81
|
+
prop: 'username',
|
|
82
|
+
label: '用户名',
|
|
83
|
+
span: 6,
|
|
84
|
+
component: ElInput,
|
|
85
|
+
attrs: {
|
|
86
|
+
placeholder: '请输入用户名',
|
|
87
|
+
clearable: true,
|
|
88
|
+
maxlength: 20,
|
|
89
|
+
},
|
|
90
|
+
events: {
|
|
91
|
+
keyup: (e) => {
|
|
92
|
+
if (e.key === 'Enter') {
|
|
93
|
+
handleSearch()
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
prop: 'realName',
|
|
100
|
+
label: '真实姓名',
|
|
101
|
+
span: 6,
|
|
102
|
+
component: ElInput,
|
|
103
|
+
attrs: {
|
|
104
|
+
placeholder: '请输入真实姓名',
|
|
105
|
+
clearable: true,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
prop: 'status',
|
|
110
|
+
label: '状态',
|
|
111
|
+
span: 6,
|
|
112
|
+
component: ElSelect,
|
|
113
|
+
attrs: {
|
|
114
|
+
placeholder: '请选择状态',
|
|
115
|
+
clearable: true,
|
|
116
|
+
},
|
|
117
|
+
children: [],
|
|
118
|
+
events: {
|
|
119
|
+
change: (_) => {
|
|
120
|
+
ElMessage.success('下拉选择变化')
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
prop: 'department',
|
|
126
|
+
label: '部门',
|
|
127
|
+
span: 6,
|
|
128
|
+
component: ElSelect,
|
|
129
|
+
attrs: {
|
|
130
|
+
placeholder: '请选择部门',
|
|
131
|
+
clearable: true,
|
|
132
|
+
filterable: true,
|
|
133
|
+
},
|
|
134
|
+
children: [],
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
prop: 'gender',
|
|
138
|
+
label: '性别',
|
|
139
|
+
span: 6,
|
|
140
|
+
component: ElSelect,
|
|
141
|
+
attrs: {
|
|
142
|
+
placeholder: '请选择性别',
|
|
143
|
+
clearable: true,
|
|
144
|
+
},
|
|
145
|
+
children: [
|
|
146
|
+
{ label: '全部', value: '' },
|
|
147
|
+
{ label: '男', value: 1 },
|
|
148
|
+
{ label: '女', value: 2 },
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
prop: 'createTime',
|
|
153
|
+
label: '创建时间',
|
|
154
|
+
span: 6,
|
|
155
|
+
component: ElDatePicker,
|
|
156
|
+
attrs: {
|
|
157
|
+
type: 'daterange',
|
|
158
|
+
rangeSeparator: '至',
|
|
159
|
+
startPlaceholder: '开始日期',
|
|
160
|
+
endPlaceholder: '结束日期',
|
|
161
|
+
clearable: true,
|
|
162
|
+
format: 'YYYY-MM-DD',
|
|
163
|
+
valueFormat: 'YYYY-MM-DD',
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
prop: 'phone',
|
|
168
|
+
label: '手机号',
|
|
169
|
+
span: 6,
|
|
170
|
+
component: ElInput,
|
|
171
|
+
attrs: {
|
|
172
|
+
placeholder: '请输入手机号',
|
|
173
|
+
clearable: true,
|
|
174
|
+
maxlength: 11,
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
prop: 'active',
|
|
179
|
+
label: '是否激活',
|
|
180
|
+
span: 6,
|
|
181
|
+
component: ElSwitch,
|
|
182
|
+
attrs: {
|
|
183
|
+
activeText: '是',
|
|
184
|
+
inactiveText: '否',
|
|
185
|
+
},
|
|
186
|
+
defaultValue: true,
|
|
187
|
+
},
|
|
188
|
+
])
|
|
189
|
+
|
|
190
|
+
// ==================== 表格配置 ====================
|
|
191
|
+
const columns = ref([
|
|
192
|
+
{
|
|
193
|
+
prop: 'id',
|
|
194
|
+
label: 'ID',
|
|
195
|
+
width: 80,
|
|
196
|
+
sortable: true,
|
|
197
|
+
// el-table-column 属性透传示例
|
|
198
|
+
'class-name': 'id-column', // 自定义列样式类名
|
|
199
|
+
resizable: false, // 禁止拖拽调整宽度
|
|
200
|
+
},
|
|
201
|
+
{ prop: 'avatar', label: '头像', slot: 'avatar', width: 80 },
|
|
202
|
+
{
|
|
203
|
+
prop: 'username',
|
|
204
|
+
label: '用户名',
|
|
205
|
+
width: 120,
|
|
206
|
+
// 透传属性
|
|
207
|
+
'show-overflow-tooltip': true, // 内容过长时显示 tooltip
|
|
208
|
+
formatter: (row, column, cellValue) => {
|
|
209
|
+
return cellValue ? `@${cellValue}` : '-'
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
prop: 'realName',
|
|
214
|
+
label: '真实姓名',
|
|
215
|
+
width: 120,
|
|
216
|
+
'min-width': 100, // 最小宽度
|
|
217
|
+
},
|
|
218
|
+
{ prop: 'gender', label: '性别', slot: 'gender', width: 80 },
|
|
219
|
+
{ prop: 'department', label: '部门', slot: 'department', width: 120 },
|
|
220
|
+
{ prop: 'status', label: '状态', slot: 'status', width: 100 },
|
|
221
|
+
{
|
|
222
|
+
prop: 'phone',
|
|
223
|
+
label: '手机号',
|
|
224
|
+
width: 130,
|
|
225
|
+
'show-overflow-tooltip': true,
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
prop: 'email',
|
|
229
|
+
label: '邮箱',
|
|
230
|
+
minWidth: 180,
|
|
231
|
+
'show-overflow-tooltip': true,
|
|
232
|
+
filters: [
|
|
233
|
+
// 筛选配置
|
|
234
|
+
{ text: 'Gmail', value: '@gmail.com' },
|
|
235
|
+
{ text: 'QQ邮箱', value: '@qq.com' },
|
|
236
|
+
],
|
|
237
|
+
'filter-method': (value, row) => {
|
|
238
|
+
return row.email.includes(value)
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
prop: 'createTime',
|
|
243
|
+
label: '创建时间',
|
|
244
|
+
width: 180,
|
|
245
|
+
sortable: true,
|
|
246
|
+
'sort-orders': ['descending', 'ascending'], // 排序顺序
|
|
247
|
+
},
|
|
248
|
+
// 操作列
|
|
249
|
+
{
|
|
250
|
+
type: 'action',
|
|
251
|
+
label: '操作',
|
|
252
|
+
width: 300,
|
|
253
|
+
fixed: 'right',
|
|
254
|
+
align: 'center',
|
|
255
|
+
headerAlign: 'center',
|
|
256
|
+
buttons: [
|
|
257
|
+
{
|
|
258
|
+
label: '查看',
|
|
259
|
+
type: 'primary',
|
|
260
|
+
link: true,
|
|
261
|
+
icon: View,
|
|
262
|
+
handler: (row) => handleView(row),
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
label: '编辑',
|
|
266
|
+
type: 'warning',
|
|
267
|
+
link: true,
|
|
268
|
+
icon: Edit,
|
|
269
|
+
handler: (row) => handleEdit(row),
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
label: '删除',
|
|
273
|
+
type: 'danger',
|
|
274
|
+
link: true,
|
|
275
|
+
icon: Delete,
|
|
276
|
+
show: true,
|
|
277
|
+
disabled: (row) => row.status === 0, // 业务时不展示
|
|
278
|
+
handler: (row) => handleDelete(row),
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
},
|
|
282
|
+
])
|
|
283
|
+
|
|
284
|
+
// ==================== 工具方法 ====================
|
|
285
|
+
const getStatusType = (status) => {
|
|
286
|
+
return status === 1 ? 'success' : 'danger'
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const getStatusText = (status) => {
|
|
290
|
+
return status === 1 ? '启用' : '禁用'
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const getDepartmentText = (department) => {
|
|
294
|
+
const departmentOptions = [
|
|
295
|
+
{ label: '技术部', value: 'tech' },
|
|
296
|
+
{ label: '产品部', value: 'product' },
|
|
297
|
+
{ label: '运营部', value: 'operation' },
|
|
298
|
+
{ label: '人力资源部', value: 'hr' },
|
|
299
|
+
{ label: '财务部', value: 'finance' },
|
|
300
|
+
]
|
|
301
|
+
const dept = departmentOptions.find((d) => d.value === department)
|
|
302
|
+
return dept ? dept.label : department
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// ==================== 数据加载 ====================
|
|
306
|
+
const loadData = async () => {
|
|
307
|
+
loading.value = true
|
|
308
|
+
try {
|
|
309
|
+
// 模拟网络延迟
|
|
310
|
+
await new Promise((resolve) => setTimeout(resolve, 500))
|
|
311
|
+
|
|
312
|
+
// 从组件获取分页信息
|
|
313
|
+
const pagination = containerRef.value?.getPagination() || {
|
|
314
|
+
currentPage: 1,
|
|
315
|
+
pageSize: 10,
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// 使用 filterUsers 进行过滤和分页
|
|
319
|
+
const result = filterUsers(mockUsers, searchParams.value, {
|
|
320
|
+
currentPage: pagination.currentPage,
|
|
321
|
+
pageSize: pagination.pageSize,
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
// 更新数据
|
|
325
|
+
tableData.value = result.list
|
|
326
|
+
total.value = result.total
|
|
327
|
+
} catch (error) {
|
|
328
|
+
console.error('加载数据失败:', error)
|
|
329
|
+
ElMessage.error('加载数据失败')
|
|
330
|
+
} finally {
|
|
331
|
+
loading.value = false
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// ==================== 事件处理 ====================
|
|
336
|
+
// 搜索
|
|
337
|
+
const handleSearch = (params) => {
|
|
338
|
+
// 更新搜索参数
|
|
339
|
+
searchParams.value = { ...params }
|
|
340
|
+
loadData()
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// 重置
|
|
344
|
+
const handleReset = () => {
|
|
345
|
+
// 重置搜索参数
|
|
346
|
+
// searchParams.value = {};
|
|
347
|
+
console.log('表单已重置,数据已刷新')
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// 选择变化
|
|
351
|
+
const handleSelectionChange = (selection) => {
|
|
352
|
+
console.log('选中的数据:', selection)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// ==================== 选择列操作方法 ====================
|
|
356
|
+
const getSelectedRows = () => {
|
|
357
|
+
if (!containerRef.value) return
|
|
358
|
+
const selectedRows = containerRef.value.getSelectionRows()
|
|
359
|
+
ElMessage.success(
|
|
360
|
+
`选中了 ${selectedRows.length} 行数据:${selectedRows.map((r) => r.username).join(', ')}`,
|
|
361
|
+
)
|
|
362
|
+
console.log('选中的行数据:', selectedRows)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const getSelectedKeys = () => {
|
|
366
|
+
if (!containerRef.value) return
|
|
367
|
+
const selectedKeys = containerRef.value.getSelectionKeys()
|
|
368
|
+
ElMessage.success(`选中了 ${selectedKeys.length} 个ID:${selectedKeys.join(', ')}`)
|
|
369
|
+
console.log('选中的ID:', selectedKeys)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const selectRows = (ids) => {
|
|
373
|
+
if (!containerRef.value) return
|
|
374
|
+
|
|
375
|
+
try {
|
|
376
|
+
// 设置选择
|
|
377
|
+
containerRef.value.setSelectionKeys(ids)
|
|
378
|
+
|
|
379
|
+
// 延迟检查选择结果
|
|
380
|
+
setTimeout(() => {
|
|
381
|
+
const selectedRows = containerRef.value.getSelectionRows()
|
|
382
|
+
const selectedKeys = containerRef.value.getSelectionKeys()
|
|
383
|
+
|
|
384
|
+
if (selectedRows.length > 0) {
|
|
385
|
+
ElMessage.success(`已选中ID为 ${ids.join(', ')} 的行,实际选中:${selectedKeys.join(', ')}`)
|
|
386
|
+
} else {
|
|
387
|
+
ElMessage.warning(`未选中任何行,请检查数据是否正确`)
|
|
388
|
+
}
|
|
389
|
+
}, 100)
|
|
390
|
+
} catch (error) {
|
|
391
|
+
console.error('选择出错:', error)
|
|
392
|
+
ElMessage.error(`选择失败:${error.message}`)
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const clearSelection = () => {
|
|
397
|
+
if (!containerRef.value) return
|
|
398
|
+
containerRef.value.clearAllSelection()
|
|
399
|
+
ElMessage.success('已清空所有选择')
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const selectAll = () => {
|
|
403
|
+
if (!containerRef.value) return
|
|
404
|
+
containerRef.value.selectAll()
|
|
405
|
+
ElMessage.success('已全选所有行')
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const checkSelection = () => {
|
|
409
|
+
if (!containerRef.value) return
|
|
410
|
+
|
|
411
|
+
// 检查特定行是否被选中
|
|
412
|
+
const isRow1Selected = containerRef.value.isRowSelected(tableData.value[0])
|
|
413
|
+
const isKey3Selected = containerRef.value.isKeySelected(3)
|
|
414
|
+
|
|
415
|
+
ElMessage.info(
|
|
416
|
+
`第一行是否选中:${isRow1Selected ? '是' : '否'},ID为3是否选中:${
|
|
417
|
+
isKey3Selected ? '是' : '否'
|
|
418
|
+
}`,
|
|
419
|
+
)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// 新增
|
|
423
|
+
const handleAdd = () => {
|
|
424
|
+
ElMessage.success('新增')
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// 查看
|
|
428
|
+
const handleView = (row) => {
|
|
429
|
+
ElMessage.success(`查看:${row.username}`)
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// 编辑
|
|
433
|
+
const handleEdit = (row) => {
|
|
434
|
+
ElMessage.success(`编辑:${row.username}`)
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// 删除
|
|
438
|
+
const handleDelete = (row) => {
|
|
439
|
+
ElMessageBox.confirm(`确定要删除用户 "${row.username}" 吗?`, '删除确认', {
|
|
440
|
+
confirmButtonText: '确定',
|
|
441
|
+
cancelButtonText: '取消',
|
|
442
|
+
type: 'warning',
|
|
443
|
+
}).then(() => {
|
|
444
|
+
// 模拟删除
|
|
445
|
+
ElMessage.success('删除成功')
|
|
446
|
+
loadData()
|
|
447
|
+
})
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// ==================== 生命周期 ====================
|
|
451
|
+
onMounted(async () => {
|
|
452
|
+
// 异步获取状态选项(模拟接口请求,延迟2秒)
|
|
453
|
+
const options = await fetchStatusOptions()
|
|
454
|
+
searchItems.value[2].children = options
|
|
455
|
+
|
|
456
|
+
// 异步获取部门选项(模拟接口请求,延迟2秒)
|
|
457
|
+
const departmentOptions = await fetchDepartmentOptions()
|
|
458
|
+
searchItems.value[3].children = departmentOptions
|
|
459
|
+
|
|
460
|
+
// 搜索条件准备好后,调用 initSearchAndLoad 初始化搜索参数并加载数据
|
|
461
|
+
// 这会自动获取 PageSearch 的初始表单数据(包含默认值和外部参数)
|
|
462
|
+
containerRef.value?.initSearchAndLoad()
|
|
463
|
+
})
|
|
464
|
+
</script>
|
|
465
|
+
|
|
466
|
+
<style scoped>
|
|
467
|
+
.demo-page {
|
|
468
|
+
height: 100%;
|
|
469
|
+
padding: 20px;
|
|
470
|
+
background: #f5f7fa;
|
|
471
|
+
display: flex;
|
|
472
|
+
flex-direction: column;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
:deep(.el-dialog__body) {
|
|
476
|
+
padding: 20px;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.selection-actions {
|
|
480
|
+
margin-top: 20px;
|
|
481
|
+
padding: 20px;
|
|
482
|
+
background: #f5f7fa;
|
|
483
|
+
border-radius: 4px;
|
|
484
|
+
display: flex;
|
|
485
|
+
gap: 10px;
|
|
486
|
+
flex-wrap: wrap;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.debug-content {
|
|
490
|
+
padding: 0 20px;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
.debug-item {
|
|
494
|
+
margin-bottom: 24px;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
.debug-label {
|
|
498
|
+
display: block;
|
|
499
|
+
font-weight: 600;
|
|
500
|
+
color: #303133;
|
|
501
|
+
margin-bottom: 8px;
|
|
502
|
+
font-size: 14px;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
.debug-value {
|
|
506
|
+
background: #f5f7fa;
|
|
507
|
+
padding: 12px;
|
|
508
|
+
border-radius: 4px;
|
|
509
|
+
font-size: 13px;
|
|
510
|
+
color: #606266;
|
|
511
|
+
margin: 0;
|
|
512
|
+
white-space: pre-wrap;
|
|
513
|
+
word-wrap: break-word;
|
|
514
|
+
border: 1px solid #e4e7ed;
|
|
515
|
+
}
|
|
516
|
+
</style>
|