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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n20-common-lib",
3
- "version": "2.20.26",
3
+ "version": "2.20.28",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -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
- const wrapperEl = document.querySelector('div#app')
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
- let columnsWidth = 0
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
- // 优先使用width,如果width不存在才使用minWidth
372
- const width = column.width || column.minWidth
373
- column['_width_'] = column['_width_'] || parseInt(width)
374
- columnsWidth += column['_width_']
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 (columnsWidth >= windowWidth) {
441
+ // 如果所有列的基础宽度总和 >= 容器宽度,不做处理
442
+ if (totalBaseWidth >= windowWidth) {
379
443
  return columns
380
444
  }
381
445
 
382
- // 否则按比例分配剩余空间
383
- return columns.map((column) => {
384
- if (!column.type) {
385
- const rate = column['_width_'] / columnsWidth
386
- // 如果column有width,则保持原width不变;如果没有width,则计算新宽度但不小于minWidth
387
- if (!column.width) {
388
- column['width'] = Math.max(windowWidth * rate, column.minWidth)
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>