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

目录

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表格多选的限制 ,限制多选可选的个数

问题:

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

解决:

/** 多选框选中数据(用户) */
//备注:this.length是多选框至多选择的个数
    handleSelectionChange(selection) {
      if (selection.length > this.length) {
        this.$message.warning(
          "至多还可添加" +
            this.length +
            "名成员,默认添加前" +
            this.length +
            "名选中的成员"
        );
        selection.forEach((item, i) => {
          if (i > this.length - 1) {
            this.$refs.multiple.toggleRowSelection(selection[i], false); //超出指定选择个数后,多选中的selection设为false
          }
        });
        selection = selection.splice(0, this.length);
      }
    },
​

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

问题:

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

解决:

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

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

问题:

解决:

样式:

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

template中:  

<div v-loading="loading" class="table-box">
        <el-table
          :data="gensetData"
          border
          size="small"
          v-if="gensetData.length > 0"
        >
          <el-table-column
            :resizable="false"
            prop="name"
            label="机组名称"
            min-width="110px"
            align="center"
          ></el-table-column>
          <el-table-column
            v-for="(item, i) in gensetcols"
            :key="i"
            align="center"
            :resizable="false"
            :property="String(i)"
            :label="item"
            min-width="110"
          >
            <template slot-scope="scope">
              <el-input
                class="text-c"
                v-if="scope.$index == 0 || scope.$index == 1"
                type="number"
                v-enterNumber
                size="mini"
                placeholder=""
                v-model="scope.row[scope.column.property]"
              ></el-input>
              <template v-else>{{ scope.row[scope.column.property] }}</template>
            </template>
          </el-table-column>
        </el-table>
        <el-table
          :data="gensetData1"
          border
          size="small"
          v-if="gensetData1.length > 0"
        >
          <el-table-column
            :resizable="false"
            prop="name"
            label="机组名称"
            min-width="110px"
            align="center"
          ></el-table-column>
          <el-table-column
            v-for="(item, i) in gensetcols1"
            :key="i"
            align="center"
            :resizable="false"
            :property="String(i)"
            :label="item"
            min-width="110"
          >
            <template slot-scope="scope">
              <el-input
                class="text-c"
                v-if="
                  scope.$index == 0 && scope.row[scope.column.property] !== ''
                "
                type="number"
                v-enterNumber
                size="mini"
                placeholder=""
                v-model="scope.row[scope.column.property]"
              ></el-input>
              <template v-else>{{ scope.row[scope.column.property] }}</template>
            </template>
          </el-table-column>
        </el-table>
      </div>

解释:

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

实现效果:

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

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

 特殊情况解决:

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

方法:

代码:

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

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

特殊情况实现:

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

解决:

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

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

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

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

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

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

问题:

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

解决:

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

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

问题:

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

解决:

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

例子:

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

.day-report-total thead {
  tr:nth-child(1) {
    th:nth-child(2) {
      background: #e2efda !important;
    }
    th:nth-child(3),
    :nth-child(5),
    :nth-child(6),
    :nth-child(7) {
      background: #fce4d6 !important;
    }
    th:nth-child(4),
    :nth-child(8),
    :nth-child(9) {
      background: #fef2cc !important;
    }
  }
  tr:nth-child(2) {
    th:nth-child(-n + 7):nth-child(n + 3) {
      background: #e2efda !important;
    }
    th:nth-child(-n + 18):nth-child(n + 8) {
      background: #fce4d6 !important;
    }
    th:nth-child(-n + 22):nth-child(n + 19) {
      background: #fef2cc !important;
    }
  }
  tr:nth-child(3) {
    th:nth-child(-n + 29) {
      background: #fef2cc !important;
    }
    th:nth-child(-n + 25) {
      background: #fce4d6 !important;
    }
    th:nth-child(-n + 8) {
      background: #e2efda !important;
    }
  }
}

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

问题:

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

解决:

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

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

例子:

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

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

解决:

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

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

解决:

indexOf

// 创建数组arr
let arr = [1, 2, 3, 4, 5];
// 得到1在arr数组中的下标0
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) 不使用新数组

for(var i=0;i<b.length;i++){
  a.push(b[i]);
}
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(字符串转数组)

let list1 = "1,11,11,1,1,1,1,1,1,1,1,1,1,1,1";

let arr1 = list1.split(",");

console.log(arr1);

例子2(数组转字符串)

let arr1 = ['1', '11', '11', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'];

console.log(arr1.join(','));

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

解决:

let a = "abc";a= a.substr(0,a.length-1);console.log(a)

let a = "abc";a= a.substring(0,a.length-1);console.log(a)

let a = "abc";a= a.substring(0,a.lastIndexOf('c'));console.log(a)

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

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

 解决:

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

  var jsonString = '[{"name":"小猫"},{"name":"小狗"},{"name":"小朋友"}]';

  console.log(JSON.parse(jsonString));

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

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

document.querySelectorAll('*').length

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

问题:

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

解决:

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

例子:

.table-box {
  height: 100%;
  display: flex;
  justify-content: space-between;
  flex-flow: row;
  .table-box-left {
    flex: 0 0 150px;
  }
  .table-box-right {
    flex: 1;
    overflow: hidden;
    margin-left: -10px;
    z-index: 3;
  }
}
 <div class="table-box">
        <div class="table-box-left">
          <ux-grid
            ref="plxTable0"
            class="day-report-table"
            :height="height"
            show-header-overflow="ellipsis"
            size="mini"
            :merge-cells="mergeCells"
            :row-class-name="tableRowClassName"
          >
            <ux-table-column
              v-for="item in columnsLeft"
              :key="item.id"
              :resizable="item.resizable"
              :field="item.prop"
              :title="item.label"
              :min-width="item.width"
              :fixed="item.fixed"
              align="center"
            />
          </ux-grid>
        </div>
        <div class="table-box-right">
          <ux-grid
            ref="plxTable"
            class="day-report-table"
            :height="height"
            show-header-overflow="ellipsis"
            size="mini"
            :span-method="arraySpanMethod1"
            :row-class-name="tableRowClassName"
            :cell-style="cellStyle"
          >
            <ux-table-column
              v-for="item in columns1Right"
              :key="item.id"
              :resizable="item.resizable"
              :field="item.prop"
              :title="item.label"
              :sortable="item.sortable"
              :min-width="item.width"
              :fixed="item.fixed"
              align="center"
            />
          </ux-grid>
        </div>
      </div>

实现效果:

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值