前言

由于在项目中使用了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的数值进行渲染页面时:

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

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

1
2
3
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’]”

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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(),时间自然是取的此时此刻的时间。这就导致传到后台的时间与我们期望的不符。

破解方法:

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

1
2
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。

1
2
<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与相同的个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 获取相同编号的数组
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中实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//合并单元格
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

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    //鼠标滑过时的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 = [];
},

循环中的输入框绑定

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

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

暂时这么多

the end;