当前位置:   article > 正文

前端开发踩坑笔记(2021-10)_ux-table-column

ux-table-column

目录

1、由于子组件修改了从父组件读取的值而出现的报错

2、对于el-table表格多选的限制 ,限制多选可选的个数

3、提取数组对象的某个属性值,组成新的字符串或数组

4、两个el-table表格(横向可能有滑动)同时展示的情况如何控制两个表同时滚动

5、表格数据特别多的时候用el-table导致页面卡顿

6、 :nth-child()选择指定的某几项进行样式渲染

7、重写elment-ui样式的时候不起作用

8、判断某一个js对象中含有的键值的个数

9、 两个对象的合并Object.assign(a,b)

10. 某个元素在数组中的索引值(下标)怎么查?

11. 将两个数组组成对象数组的快捷方式

12. 字符串与数字之间的互相转换

13. 字符串与数组之间的互相转换

14. 删除字符串的最后一个字符

15. 字符串和对象之间的互相转换

16. 查询当前窗口的dom节点个数

17. 使用umy-ui时固定列不显示问题


1、由于子组件修改了从父组件读取的值而出现的报错

问题:

vue.min.js:6 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "data" found in

原因:

子组件修改了props方法从父组件传过来的参数

解决:

在data中另外定义一个值,用来接收来自父组件的参数,在 computed中进行赋值,如果直接只在data中赋值那么该数只会在该子组件被创建时赋值一次,在watch中进行监听。

2、对于el-table表格多选的限制 ,限制多选可选的个数

问题:

官方文档中的多选为全选,在实际的业务需求中可能存在只能选择固定几项的情况

解决:

  1. /** 多选框选中数据(用户) */
  2. //备注:this.length是多选框至多选择的个数
  3.    handleSelectionChange(selection) {
  4.      if (selection.length > this.length) {
  5.        this.$message.warning(
  6.          "至多还可添加" +
  7.            this.length +
  8.            "名成员,默认添加前" +
  9.            this.length +
  10.            "名选中的成员"
  11.       );
  12.        selection.forEach((item, i) => {
  13.          if (i > this.length - 1) {
  14.            this.$refs.multiple.toggleRowSelection(selection[i], false); //超出指定选择个数后,多选中的selection设为false
  15.         }
  16.       });
  17.        selection = selection.splice(0, this.length);
  18.     }
  19.   },

3、提取数组对象的某个属性值,组成新的字符串或数组

问题:

存在数组对象 arr=[{x:1}, {x:2}, {x:3} ],若想将x中的值组成一个新字符串或数组,如何处理?

解决:

  1. let extractByKey = function(arr,key,resultType='String',separator=',') {
  2.    let resultArr = [];
  3.    arr.map(item => {
  4.        if(item[key]) resultArr.push(item[key]);
  5.   })//遍历数组对象
  6.    if(resultType==='Array') return resultArr;
  7.    else if(resultType==='String')return resultArr.join(separator)
  8.    else throw new Error("resultType无效");
  9. }

4、两个el-table表格(横向可能有滑动)同时展示的情况如何控制两个表同时滚动

问题:

解决:

样式:

  1. <style lang="scss" scoped >
  2. .table-box {
  3.  height: 192px;
  4.  overflow-x: scroll;//给盒子加滚动
  5.  width: 100%;
  6. }
  7. .table-box .el-table {
  8.  min-width: 1470px !important;//根据实际情况设定最小的宽度
  9. }
  10. </style>

template中:  

  1. <div v-loading="loading" class="table-box">
  2.        <el-table
  3.          :data="gensetData"
  4.          border
  5.          size="small"
  6.          v-if="gensetData.length > 0"
  7.        >
  8.          <el-table-column
  9.            :resizable="false"
  10.            prop="name"
  11.            label="机组名称"
  12.            min-width="110px"
  13.            align="center"
  14.          ></el-table-column>
  15.          <el-table-column
  16.            v-for="(item, i) in gensetcols"
  17.            :key="i"
  18.            align="center"
  19.            :resizable="false"
  20.            :property="String(i)"
  21.            :label="item"
  22.            min-width="110"
  23.          >
  24.            <template slot-scope="scope">
  25.              <el-input
  26.                class="text-c"
  27.                v-if="scope.$index == 0 || scope.$index == 1"
  28.                type="number"
  29.                v-enterNumber
  30.                size="mini"
  31.                placeholder=""
  32.                v-model="scope.row[scope.column.property]"
  33.              ></el-input>
  34.              <template v-else>{{ scope.row[scope.column.property] }}</template>
  35.            </template>
  36.          </el-table-column>
  37.        </el-table>
  38.        <el-table
  39.          :data="gensetData1"
  40.          border
  41.          size="small"
  42.          v-if="gensetData1.length > 0"
  43.        >
  44.          <el-table-column
  45.            :resizable="false"
  46.            prop="name"
  47.            label="机组名称"
  48.            min-width="110px"
  49.            align="center"
  50.          ></el-table-column>
  51.          <el-table-column
  52.            v-for="(item, i) in gensetcols1"
  53.            :key="i"
  54.            align="center"
  55.            :resizable="false"
  56.            :property="String(i)"
  57.            :label="item"
  58.            min-width="110"
  59.          >
  60.            <template slot-scope="scope">
  61.              <el-input
  62.                class="text-c"
  63.                v-if="
  64.                  scope.$index == 0 && scope.row[scope.column.property] !== ''
  65.                "
  66.                type="number"
  67.                v-enterNumber
  68.                size="mini"
  69.                placeholder=""
  70.                v-model="scope.row[scope.column.property]"
  71.              ></el-input>
  72.              <template v-else>{{ scope.row[scope.column.property] }}</template>
  73.            </template>
  74.          </el-table-column>
  75.        </el-table>
  76.      </div>

解释:

给表格设定最小的宽度,外侧包一层div,对div加横向滚动的样式,这样就可以实现两个表格的同时横向滚动

实现效果:

特殊情况(需左列固定):

表格如果需要进行左列的固定,即横向数据特别多的情况之下左列又需要固定,就不能采取上面的做法,例如下面的情况需要固定。

 特殊情况解决:

思路:只需要对两个表格的dom节点进行监听,使上下两个表格同时滚动

方法:

代码:

  1. this.dom1 = this.$refs.tableData.bodyWrapper;
  2.        this.dom2 = this.$refs.tableData1.bodyWrapper;
  3.        // this.dom1 = document.getElementsByClassName(
  4.        //   "el-table__body-wrapper"
  5.        // )[0];
  6.        // this.dom2 = document.getElementsByClassName(
  7.        //   "el-table__body-wrapper"
  8.        // )[1];
  9.    /** 表格滚动 */
  10.    listenerScroll() {
  11.      this.dom1.addEventListener("scroll", () => {
  12.        // 横滚
  13.        this.dom2.scrollLeft = this.dom1.scrollLeft;
  14.     });
  15.      this.dom2.addEventListener("scroll", () => {
  16.        // 横滚
  17.        this.dom1.scrollLeft = this.dom2.scrollLeft;
  18.     });
  19.   },
这时候要隐藏掉第一个el-table的滚动条,但找不到滚动条的类名,只需要给第二个el-table写样式(遮盖住滚动条)
  1. .tableData1 {
  2.  margin-top: -12px!important;
  3.  z-index: 2;
  4. }

备注:另一种数据较多情况下,若需两个表格同时竖向滚动,则使用scrollTop即可

特殊情况实现:

5、表格数据特别多的时候用el-table导致页面卡顿

解决:

需要使用umy-ui进行表格渲染

umy-ui开发文档 - 为开发者准备的基于 Vue 2.0 的桌面端组件库,完美解决表格万级数据渲染卡顿问题

值得一提的是用umy-ui渲染的时候,遇到横向纵向数据都很多的情况,但是又是多表头(单表头不支持虚拟表格),用两种方法进行解决(仅思路):

(1).使用两个表,通过重写表格样式进行两个表格的滑动联动(不能用div进行包裹,因为数据特别多的情况下dom节点渲染会很多,不会解决页面卡顿问题,采用问题4中特殊情况的相同处理方式)

(2).使用一个表,但是多表头的部分使用数据进行模拟,再进行行列的合并(这样会导致向下滑动的时候表头也会跟着滑动,所以第一种方式更好)

6、 :nth-child()选择指定的某几项进行样式渲染

问题:

重写el-table的样式时,或是其他有多种子元素不同样式时,需要对选定的第几项或某几项的样式进行特殊处理

解决:

  1. /* 选择第n个,n位数字 */
  2. :nth-child(n)
  3. 选择列表中的偶数标签
  4. :nth-child(2n)
  5. 选择列表中的奇数标签
  6. :nth-child(2n-1)
  7. 选择前几个元素
  8. /*【负方向范围】选择第1个到第6个 */
  9. :nth-child(-n+6){}
  10. 从第几个开始选择
  11. /*【正方向范围】选择从第6个开始的,直到最后 */
  12. :nth-child(n+6){}
  13. 两者结合使用,可以限制选择某一个范围
  14. /*【限制范围】选择第6个到第9个,取两者的交集*/
  15. :nth-child(-n+9):nth-child(n+6){}
  16. 选择列表中的倒数第n个标签 n为数字
  17. :nth-last-child(n)
​例子:(在例子中,注释部分和非注释部分实现效果相同)

7、重写elment-ui样式的时候不起作用

问题:

重写elment-ui样式的时候不起作用

解决:

在重写elment-ui样式的时候,可以给el-table加一个专属的class,而且在写样式的时候不能使用scoped(会失效)­­­

例子:

(此例子中是对el-table的指定单元小格进行样式复写,实际开发中根据具体情况而定)

  1. .day-report-total thead {
  2. tr:nth-child(1) {
  3. th:nth-child(2) {
  4. background: #e2efda !important;
  5. }
  6. th:nth-child(3),
  7. :nth-child(5),
  8. :nth-child(6),
  9. :nth-child(7) {
  10. background: #fce4d6 !important;
  11. }
  12. th:nth-child(4),
  13. :nth-child(8),
  14. :nth-child(9) {
  15. background: #fef2cc !important;
  16. }
  17. }
  18. tr:nth-child(2) {
  19. th:nth-child(-n + 7):nth-child(n + 3) {
  20. background: #e2efda !important;
  21. }
  22. th:nth-child(-n + 18):nth-child(n + 8) {
  23. background: #fce4d6 !important;
  24. }
  25. th:nth-child(-n + 22):nth-child(n + 19) {
  26. background: #fef2cc !important;
  27. }
  28. }
  29. tr:nth-child(3) {
  30. th:nth-child(-n + 29) {
  31. background: #fef2cc !important;
  32. }
  33. th:nth-child(-n + 25) {
  34. background: #fce4d6 !important;
  35. }
  36. th:nth-child(-n + 8) {
  37. background: #e2efda !important;
  38. }
  39. }
  40. }

8、判断某一个js对象中含有的键值的个数

问题:

获取js对象中包含多少个对象

解决:

判断对象的keys值个数Object.keys(table).length

Object.keys()接收一个对象作为参数,并返回其所有(自己的)可枚举属性的数组。

例子:

  1. let table = {
  2. name: "",
  3. sex: "",
  4. age: "",
  5. };
  6. console.log(Object.keys(table).length);//3

9、 两个对象的合并Object.assign(a,b)

解决:

  1. var a = {'grandId': '1', 'grandName': '一年级'}
  2. var b = {'clazzId': '2', 'clazzName': '1班'}
  3. let result = Object.assign(a, b)
  4. /**
  5. result = {
  6. 'grandId': '1', 'grandName': '一年级',
  7. 'clazzId': '2', 'clazzName': '1班'
  8. }
  9. */

10. 某个元素在数组中的索引值(下标)怎么查?

解决:

indexOf

  1. // 创建数组arr
  2. let arr = [1, 2, 3, 4, 5];
  3. // 得到1在arr数组中的下标0
  4. arr.indexOf(1); // 0

11. 将两个数组组成对象数组的快捷方式

解决:

推荐使用 arr1.push(...arr2)

数组拼接的四种方法:
var a = [1,2,3,4,5,6];
var b=["foo","bar", "fun"];
最终的结果是:
[1,2,3,4,5,6,"foo","bar","fun"]

(1) concat

c=a.concat(b);

c是新数组,此时的内存使用有a b c 三个数组``

(2) 不使用新数组

  1. for(var i=0;i<b.length;i++){
  2.   a.push(b[i]);
  3. }
  4. b=null;

没有新的数组的创建,对于内存更优,拼接完成之后对数组b清空。 (3) apply(推荐)

a.push.apply(a,b) 

(4)es6的写法(推荐)

a.push.apply(a,b) 

12. 字符串与数字之间的互相转换

解决:

数字转字符串:(1)加空字符串(2)用String()方法

字符串转数字:(1)减0(2)用Number方法

13. 字符串与数组之间的互相转换

解决:

String.split() 执行的操作与 Array.join 执行的操作是相反的。

字符串转数组:String.split()

split() 方法用于把一个字符串分割成字符串数组。

数组转字符串:Array.join

join() 方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。

例子:

例子1(字符串转数组)

  1. let list1 = "1,11,11,1,1,1,1,1,1,1,1,1,1,1,1";
  2. let arr1 = list1.split(",");
  3. console.log(arr1);

例子2(数组转字符串)

  1. let arr1 = ['1', '11', '11', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'];
  2. console.log(arr1.join(','));

14. 删除字符串的最后一个字符

解决:

  1. let a = "abc";a= a.substr(0,a.length-1);console.log(a)
  2. let a = "abc";a= a.substring(0,a.length-1);console.log(a)
  3. let a = "abc";a= a.substring(0,a.lastIndexOf('c'));console.log(a)

备注:第三种情况只适合已知最后一个字符是什么的情况

15. 字符串和对象之间的互相转换

 解决:

// 字符串转化为 对象JSON.parse(jsonString)

  1. var jsonString = '[{"name":"小猫"},{"name":"小狗"},{"name":"小朋友"}]';
  2. console.log(JSON.parse(jsonString));

// 对象转为字符串 JSON.stringify(obj)

16. 查询当前窗口的dom节点个数

document.querySelectorAll('*').length

17. 使用umy-ui时固定列不显示问题

问题:

在使用Umy-ui时,若有行列的合并且有固定列,假设固定了左侧的列项,向右滚动时则会出现固定列数据消失的情况。

解决:

将表格进行拆分,拆分为左右两个表格,且两个表格贴合,对两个表格进行竖向滚动的同步处理(第四个问题的处理方式),这样视觉上是一个表格。分别进行合并行列的处理。

例子:

  1. .table-box {
  2. height: 100%;
  3. display: flex;
  4. justify-content: space-between;
  5. flex-flow: row;
  6. .table-box-left {
  7. flex: 0 0 150px;
  8. }
  9. .table-box-right {
  10. flex: 1;
  11. overflow: hidden;
  12. margin-left: -10px;
  13. z-index: 3;
  14. }
  15. }
  16. <div class="table-box">
  17. <div class="table-box-left">
  18. <ux-grid
  19. ref="plxTable0"
  20. class="day-report-table"
  21. :height="height"
  22. show-header-overflow="ellipsis"
  23. size="mini"
  24. :merge-cells="mergeCells"
  25. :row-class-name="tableRowClassName"
  26. >
  27. <ux-table-column
  28. v-for="item in columnsLeft"
  29. :key="item.id"
  30. :resizable="item.resizable"
  31. :field="item.prop"
  32. :title="item.label"
  33. :min-width="item.width"
  34. :fixed="item.fixed"
  35. align="center"
  36. />
  37. </ux-grid>
  38. </div>
  39. <div class="table-box-right">
  40. <ux-grid
  41. ref="plxTable"
  42. class="day-report-table"
  43. :height="height"
  44. show-header-overflow="ellipsis"
  45. size="mini"
  46. :span-method="arraySpanMethod1"
  47. :row-class-name="tableRowClassName"
  48. :cell-style="cellStyle"
  49. >
  50. <ux-table-column
  51. v-for="item in columns1Right"
  52. :key="item.id"
  53. :resizable="item.resizable"
  54. :field="item.prop"
  55. :title="item.label"
  56. :sortable="item.sortable"
  57. :min-width="item.width"
  58. :fixed="item.fixed"
  59. align="center"
  60. />
  61. </ux-grid>
  62. </div>
  63. </div>

实现效果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/115437
推荐阅读
相关标签
  

闽ICP备14008679号