n20-common-lib 2.20.26 → 2.20.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
@sort-change="(val) => customSortMethod(val)"
|
|
48
48
|
@filter-change="filterChange"
|
|
49
49
|
@checkbox-change="handleSelectionChange"
|
|
50
|
+
@cell-click="handleCellClick"
|
|
50
51
|
>
|
|
51
52
|
<template v-for="(item, i) in _columns">
|
|
52
53
|
<slot v-if="item.slotName" :name="item.slotName" :column="item"></slot>
|
|
@@ -325,6 +326,56 @@ export default {
|
|
|
325
326
|
const val1 = this.$refs.vxeTable.getCheckboxReserveRecords()
|
|
326
327
|
this.$emit('selection-change-method', [...val, ...val1], row)
|
|
327
328
|
},
|
|
329
|
+
// 点击行勾选/取消勾选
|
|
330
|
+
handleCellClick({ row, column, $event }) {
|
|
331
|
+
this.$emit('cell-click', { row, column, $event })
|
|
332
|
+
// 如果点击的是 checkbox 列,不处理(由原生的 checkbox 处理)
|
|
333
|
+
if (column.type === 'checkbox') {
|
|
334
|
+
return
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// 检查点击的目标元素是否是按钮或链接
|
|
338
|
+
// 需要检测多种按钮类型:
|
|
339
|
+
// - button: 原生按钮标签
|
|
340
|
+
// - .el-button: Element UI 按钮组件
|
|
341
|
+
// - .n20-button: n20 项目按钮组件
|
|
342
|
+
// - [class*="button"]: 包含 button 类名的元素
|
|
343
|
+
// - [class*="el-link--inner"]: Element UI 链接组件内部元素
|
|
344
|
+
// - a[href]: 链接标签
|
|
345
|
+
const target = $event.target
|
|
346
|
+
const clickedButton = target.closest(
|
|
347
|
+
'button, .el-button, .n20-button, [class*="button"], [class*="el-link--inner"], a[href]'
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
// 如果点击的是按钮或链接,不触发行勾选
|
|
351
|
+
if (clickedButton) {
|
|
352
|
+
return
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// 如果 closest 没找到,检查父元素的类名是否包含操作相关的关键词
|
|
356
|
+
if (!clickedButton && target.parentElement) {
|
|
357
|
+
const parentClass = target.parentElement.className || ''
|
|
358
|
+
// 检测父元素是否包含:operate(操作)、btn(按钮)、button(按钮) 等关键词
|
|
359
|
+
if (parentClass.includes('operate') || parentClass.includes('btn') || parentClass.includes('button')) {
|
|
360
|
+
return
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// 检查该行是否可以被勾选
|
|
365
|
+
let canCheck = true
|
|
366
|
+
if (typeof this.forbidSelect === 'function') {
|
|
367
|
+
const forbidResult = this.forbidSelect({ row })
|
|
368
|
+
// 只有当 forbidSelect 明确返回 true 时,才禁止勾选
|
|
369
|
+
canCheck = forbidResult !== true
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (canCheck) {
|
|
373
|
+
// 切换该行的勾选状态
|
|
374
|
+
this.$refs.vxeTable.toggleCheckboxRow(row)
|
|
375
|
+
this.key++ // 强制刷新 checkbox 显示
|
|
376
|
+
this.handleSelectionChange(row)
|
|
377
|
+
}
|
|
378
|
+
},
|
|
328
379
|
sizeUp(size) {
|
|
329
380
|
this.sizeC = size
|
|
330
381
|
this.$emit('update:size', size)
|
|
@@ -340,20 +391,25 @@ export default {
|
|
|
340
391
|
_width_: 0
|
|
341
392
|
}
|
|
342
393
|
})
|
|
343
|
-
|
|
394
|
+
|
|
395
|
+
// 优先使用表格容器的宽度,如果没有则使用app容器宽度
|
|
396
|
+
let wrapperEl = this.$refs.vxeTable?.$el
|
|
397
|
+
if (!wrapperEl) {
|
|
398
|
+
wrapperEl = document.querySelector('div#app')
|
|
399
|
+
}
|
|
344
400
|
if (!wrapperEl) {
|
|
345
401
|
return columns
|
|
346
402
|
}
|
|
347
403
|
const { width: windowWidth } = wrapperEl.getBoundingClientRect()
|
|
348
|
-
|
|
404
|
+
console.log(windowWidth, 'windowWidth')
|
|
349
405
|
// 定义每个字符的平均宽度(像素)
|
|
350
406
|
const CHAR_WIDTH = 20 // 根据实际字体大小调整
|
|
351
407
|
const PADDING = 20 // 左右padding
|
|
352
408
|
|
|
353
409
|
function calc(columns) {
|
|
354
|
-
|
|
410
|
+
// 计算所有列的基础宽度总和
|
|
411
|
+
let totalBaseWidth = 0
|
|
355
412
|
|
|
356
|
-
// 先计算每列的基础宽度
|
|
357
413
|
columns.forEach((column) => {
|
|
358
414
|
if (column.static && column.label === $lc('操作') && !column.width && !column.minWidth) {
|
|
359
415
|
column.width = 80
|
|
@@ -368,29 +424,36 @@ export default {
|
|
|
368
424
|
column.minWidth = Math.ceil(textLength * CHAR_WIDTH + PADDING)
|
|
369
425
|
}
|
|
370
426
|
|
|
371
|
-
//
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
|
|
427
|
+
// 计算基础宽度:有width的用width,没有的用minWidth
|
|
428
|
+
const widthValue = column.width || column.minWidth || 0
|
|
429
|
+
// 处理不同格式的宽度:数字、"100"、"100px"
|
|
430
|
+
let baseWidth = 0
|
|
431
|
+
if (typeof widthValue === 'number') {
|
|
432
|
+
baseWidth = widthValue
|
|
433
|
+
} else if (typeof widthValue === 'string') {
|
|
434
|
+
// 提取字符串中的数字部分
|
|
435
|
+
baseWidth = parseInt(widthValue) || 0
|
|
436
|
+
}
|
|
437
|
+
column['_baseWidth_'] = baseWidth
|
|
438
|
+
totalBaseWidth += baseWidth
|
|
375
439
|
})
|
|
376
440
|
|
|
377
|
-
//
|
|
378
|
-
if (
|
|
441
|
+
// 如果所有列的基础宽度总和 >= 容器宽度,不做处理
|
|
442
|
+
if (totalBaseWidth >= windowWidth) {
|
|
379
443
|
return columns
|
|
380
444
|
}
|
|
381
445
|
|
|
382
|
-
//
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}
|
|
390
|
-
return column
|
|
446
|
+
// 否则,所有列都按比例扩展以撑满容器
|
|
447
|
+
const scaleRate = windowWidth / totalBaseWidth
|
|
448
|
+
|
|
449
|
+
columns.forEach((column) => {
|
|
450
|
+
if (!column.type && !column.isResize) {
|
|
451
|
+
// 按比例扩展列宽,向上取整避免小数宽度
|
|
452
|
+
column.width = Math.ceil(column['_baseWidth_'] * scaleRate)
|
|
391
453
|
}
|
|
392
|
-
return column
|
|
393
454
|
})
|
|
455
|
+
|
|
456
|
+
return columns
|
|
394
457
|
}
|
|
395
458
|
|
|
396
459
|
return calc(columns)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<vxe-column :field="$attrs.prop" :title="$attrs.label" v-bind="$attrs">
|
|
3
|
-
<OperateBtns slot-scope="{ row, $index }" :btn-list="btnList" :row="row" @command="c => $emit(c, row, $index)" />
|
|
3
|
+
<OperateBtns slot-scope="{ row, $index }" :btn-list="btnList" :row="row" @command="(c) => $emit(c, row, $index)" />
|
|
4
4
|
</vxe-column>
|
|
5
5
|
</template>
|
|
6
6
|
<script>
|