Element UI笔记

本文主要记录使用Element UI组件中碰到的问题。

  • 树形控件el-tree自定义节点内容,删除节点不更新DOM的问题
  • 上传控件el-upload单文件上传覆盖已有文件方法
  • 多选框控件el-checkbox传id值,同时页面显示中文标签的方法

树形控件el-tree自定义节点内容,删除节点不更新DOM的问题

问题

删除的流程大致是先通过接收的两个参数node和data, 通过node.parent.data.children拿到子节点数据,然后通过遍历const index = children.findIndex(d => d.id === data.id)拿到节点的index,执行children.splice(index, 1),一模一样的代码可是我的DOM并没有更新(就是没有删掉)。

解决办法

猜测是因为不能监听到数组内的数据变化,没有更新DOM

因此我用了JSON.parse(JSON.stringify(data))把删除后的整个原始数据转换一下就可以了。

1
2
3
4
5
6
7
remove(node, data) {
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex(d => d.id === data.id);
children.splice(index, 1);
this.treeData = JSON.parse(JSON.stringify(this.treeData))
},

官网示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<div class="custom-tree-container">
<div class="block">
<p>使用 scoped slot</p>
<el-tree
:data="data"
show-checkbox
node-key="id"
default-expand-all
:expand-on-click-node="false">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span>
<el-button
type="text"
size="mini"
@click="() => append(data)">
Append
</el-button>
<el-button
type="text"
size="mini"
@click="() => remove(node, data)">
Delete
</el-button>
</span>
</span>
</el-tree>
</div>
</div>

<script>
let id = 1000;

export default {
data() {
const data = [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}];
return {
data: JSON.parse(JSON.stringify(data)),
data: JSON.parse(JSON.stringify(data))
}
},

methods: {
append(data) {
const newChild = { id: id++, label: 'testtest', children: [] };
if (!data.children) {
this.$set(data, 'children', []);
}
data.children.push(newChild);
},

remove(node, data) {
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex(d => d.id === data.id);
children.splice(index, 1);
},
}
};
</script>

<style>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>

上传控件el-upload单文件上传覆盖已有文件方法

需求

单选文件上传,每次只允许一个文件上传,当已选择了文件再次点击选择其他的文件时,需要覆盖上次选择的文件。但是看了看el-upload的开发文档,好像不支持这个需求,选择新的文件后无法替代旧的。研究了下源码找到了实现方法。

解决方案

利用el-upload的on-exceed,该方法是文件超出个数限制时的钩子,当把上传文件数最大设置为1的时候再次选择新文件时会触发这个方法,利用这个对文件进行重新赋值即可。

on-exceed的回调函数有两个参数function(files, fileList),files为当前选择的文件,fileList已经选择后的文件(上次选择的),可以对fileList进行赋值来修改上传时的文件。但是只修改fileList是不够的,还需要修改el-upload里的uploadFiles,保持数据同步,不然上传后的回调函数里的字段会报错

HTML部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<el-upload
class="col-md-6 col-lg-6 col-xs-12"
ref="rebateUpload"
:multiple="false"
:action="config.interfaceIP+'xxx'"
:headers=" {'X-CSRF-TOKEN':this.config.csrfToken}"
:data="{type:uploadType}"
:before-upload="()=>{$loading({lock: true,text: '上传中...',spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'});}"
:on-success="uploadRequest"
:limit="1"
:on-exceed="uploadExceed"
:auto-upload="false">
<el-button slot="trigger" type="primary">选取文件</el-button>
<el-button style="margin-left: 10px;" type="success" @click="()=>{$refs['rebateUpload'].submit()}">
上传
</el-button>
</el-upload>

注:该上传为手动上传

JS部分:

1
2
3
4
5
6
uploadExceed(files, fileList) {
this.$set(fileList[0], 'raw', files[0]);
this.$set(fileList[0], 'name', files[0].name);
this.$refs['rebateUpload'].clearFiles();//清除文件
this.$refs['rebateUpload'].handleStart(files[0]);//选择文件后的赋值方法
},

总结:因为单选所以只要覆盖第一个值就可以了,fileList[0]里的raw为选中的文件,同时替换掉文件的文件名name,再清除文件为el-upload里的uploadFiles重新赋值。

多选框控件el-checkbox传id值,同时页面显示中文标签的方法

需求

Element的官方案例中都是以中文传递参数,而我们在实际的工作中经常以id入库。我希望能够改成传id等标识,展示在页面上的是中文标签。

官方示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<el-checkbox-group v-model="checkList">
<el-checkbox label="复选框 A"></el-checkbox>
<el-checkbox label="复选框 B"></el-checkbox>
<el-checkbox label="复选框 C"></el-checkbox>
<el-checkbox label="禁用" disabled></el-checkbox>
<el-checkbox label="选中且禁用" disabled></el-checkbox>
</el-checkbox-group>


//data 里面
data () {
return {
//以中文传值
checkList: ['选中且禁用','复选框 A']
};
}

解决方案

如果el-checkbox标签之间不写任何内容,那么页面上显示的也是label的内容,但是如果在el-checkbox标签里面加上,页面上显示的就是name。示例如下:

1
2
3
4
5
6
7
8
9
10
<el-checkbox-group v-model="value" >
<el-checkbox v-for="city in cities" :label="city.id" :key="city.id">{{city.name}}</el-checkbox>
</el-checkbox-group>

data() {
return {
value: [],
cities: [{name:'北京',id:'1'}, {name:'武汉',id:'2'},{name:'深圳',id:'3'}];
}
};

参考


----------- 本文结束啦感谢您阅读 -----------

赞赏一杯咖啡

欢迎关注我的其它发布渠道