前言

由于在项目中使用了Element作为前端开发的组件库。初次接触Element的我遇到了很多的问题,其中有一部分的解决方法与思路总结在这里。以后可以进行查阅。

介绍

Element是一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。首先它是基于一套用于构建用户界面的渐进式框架的vue,所以首先要有vue的开发经验。

Element中文官网:https://element.eleme.cn/#/zh-CN

源代码仓库:https://github.com/ElemeFE/element

Element属于饿了么团队开发维护。有一段时间并没有维护,说是开发了新的一套组件库,前些日子正好看到又重新有人提交代码。新的基于vue3.0的也已经放出来了。声明如下:

Element will stay with Vue 2.x

For Vue 3.0, we recommend using Element Plus from the same team

使用

犹如其他基于vue的组件一样,使用自定义标签完成镶嵌:<el-**>,组件上还能使用特性属性值与事件来实现element的特色。具体可以访问官网查看。

具体使用中的问题与总结

在使用中其实大部分问题都和vue相关,因为我本身vue开发还不是十分熟悉,也就依葫芦画瓢的地步。

数据加载时机

当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。

当我需要使用data的数值进行渲染页面时:

 <span class="notice"><span style="color: red">*</span>买家留言:{{drawerOrderInfo.productList[0].buyerMessage|formatBuyerMessage}}</span>

data() {return {}}中的数据就必须进行初始化。否则会报undefined。

drawerOrderInfo: {
        productList:[{buyerMessage: null}]
      },

所以这是个很容易犯的错误。针对对象,在dom渲染时使用的属性,一定要在数据定义时进行初始化。

DatePicker 日期选择器

问题出在我们仅使用选择日期范围时,传到后台的数值包含了time。正常情况下我们使用带快捷选项的日期选择器,会出现选择的日期范围为【开始日期+点击时间点——结束日期+点击时间点】例如【2020-12-21T16:00:00.000Z,2020-12-22T16:00:00.000Z】而实际上我们业务可能需要的是开始时间的零时到结束时间的24时,即【2020-12-21T00:00:00.000Z,2020-12-22T23:59:59.000Z】。问题出在了带快捷选项上。

首先我们需要设置默认时间:

选择日期范围时,默认情况下,起始日期和结束日期的时间部分均为当天的 0 点 0 分 0 秒。通过default-time可以分别指定二者的具体时刻。default-time接受一个数组,其中的值为形如12:00:00的字符串,第一个值控制起始日期的时刻,第二个值控制结束日期的时刻。

:default-time=”[‘00:00:00’, ‘23:59:59’]”

其次,认识到快捷选项的问题点:

 pickerOptions: {
          shortcuts: [{
            text: '本月',
            onClick(picker) {
              picker.$emit('pick', [new Date(), new Date()]);
            }
          }, {
            text: '今年至今',
            onClick(picker) {
              const end = new Date();
              const start = new Date(new Date().getFullYear(), 0);
              picker.$emit('pick', [start, end]);
            }
          }, {
            text: '最近六个月',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setMonth(start.getMonth() - 6);
              picker.$emit('pick', [start, end]);
            }
          }]
        },

即在设置start与end时,使用了new Date(),时间自然是取的此时此刻的时间。这就导致传到后台的时间与我们期望的不符。

破解方法:

传入后台前,针对时间进行重新拼接。

startTime = this.createTimeArr[0].substring(0,this.createTimeArr[0].indexOf(' ')).concat(' ',this.defaultTime[0]) ;
        endTime = this.createTimeArr[1].substring(0,this.createTimeArr[1].indexOf(' ')).concat(' ',this.defaultTime[1]) ;

同一页面多Form 表单校验

在开发中,遇到了同一个页面。有两个form,然后需要分别校验。但设置不同的:rules与ref值,仍然无法校验。当然:model也是不同的,element也没有给出怎么解决。直到我在两个form中加入了不同的key。

    <el-form class="modifyFormId" :model="modifyFormInfo" :rules="rules" ref="modifyFormInfo" :label-position="position"
             label-width="150px" v-if="modifyForm" key="modifyFormInfo">`

所以解决方法是用key关键字进行区分。比较低级的错误。

table的合并单元格

当某些行相同需要进行合并时,就需要进行table合并。在table属性上加入:span-method=”objectSpanMethod”。

通过给table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspancolspan的对象。

实例:合并重复的行。

思路:首先获得相同编号的数组,将行特征码为合并依据,只有这些特征码统一,且是多行数据,记录下它的rowindex与相同的个数。

// 获取相同编号的数组
    getOrderNumber() {
      this.orderNoIndexArr=[];
      let OrderObj = {}
      this.list.forEach((element, index) => {
        element.rowIndex = index;
        //只有待发货才能进行合并

        if (OrderObj[element.orderNo+element.status]) {
          OrderObj[element.orderNo+element.status].push(index)
        } else{
          OrderObj[element.orderNo+element.status] = []
          OrderObj[element.orderNo+element.status].push(index)
        }
      })
      // 将数组长度大于1的值 存储到this.OrderIndexArr(也就是需要合并的项)
      for (let k in OrderObj) {
        if (OrderObj[k].length > 1) {
          this.orderNoIndexArr.push(OrderObj[k])
        }
      }
    },

之后在objectSpanMethod中实现。

//合并单元格
    objectSpanMethod({row, column, rowIndex, columnIndex}) {
      if (columnIndex == 1 || columnIndex == 6 || columnIndex == 4 || columnIndex == 5 || columnIndex == 7) {
        for (let i = 0; i < this.orderNoIndexArr.length; i++) {
          let element = this.orderNoIndexArr[i]
          for (let j = 0; j < element.length; j++) {
            let item = element[j]
            if (rowIndex === item) {
              if (j == 0) {
                return {
                  rowspan: element.length,
                  colspan: 1
                }
              } else {
                return {
                  rowspan: 1,
                  colspan: 0
                }
              }
            }
          }
        }
      }
    },

效果如下:

同时,也可解决鼠标滑过时的样式问题。

具体可见https://blog.csdn.net/u013558749/article/details/82257168

离线文件:blog.csdn.net-element-ui 实现行合并.pdf

代码如下:

    //鼠标滑过时的css样式修改
    tableRowClassName({row, rowIndex}) {
      let arr = this.hoverOrderArr
      for (let i = 0; i < arr.length; i++) {
        if (rowIndex == arr[i]) {
          return 'hovered-row'
        }
      }
    },
//鼠标滑过时的css样式修改
    cellMouseEnter(row, column, cell, event) {
      this.rowIndex = row.rowIndex;
      this.hoverOrderArr = [];
      this.orderNoIndexArr.forEach(element => {
        if (element.indexOf(this.rowIndex) >= 0) {
          this.hoverOrderArr = element
        }
      })
    },
//鼠标滑过时的css样式修改
    cellMouseLeave(row, column, cell, event) {
      this.rowIndex = '-1'
      this.hoverOrderArr = [];
    },

循环中的输入框绑定

当我们不确定输入框为多少时,循环中设置循环索引,将输入框数值赋值给一个数组,下标即循环索引。

<div v-for="(productAttr,idx) in selectProductAttr">
    ...
    <el-input v-model="addProductAttrValue[idx]" style="width: 160px;margin-left: 10px" clearable></el-input>
...

暂时这么多

the end;