春暖花会开,如果你曾经经历过冬天,那么你就会有春色!如果你正在付出,那么总有一天你会拥有花开满园。
之前的一篇文章已经讲解过如何实现el-tree和el-table的数据点击联动,以及右键可编辑树:【Vue入门实践】Element-UI 树形组件el-tree的组件封装 =>实现组织机构树Tree => 使用vue-content-menu定制可编辑树结构editableTree_Sabrina_cc的博客-CSDN博客
实现效果如图:
目录
一、概述实现效果
1.UI给出的页面设计样式
2.最终的前端 实现页面效果
1. 【新增】点击文件夹后->点击新增,会在选中的文件夹下新建文件夹目录;如果选中‘全部’或者不选,则直接在全部目录下新建文件夹目录。
2.【删除】点击删除按钮,确认弹框后删除该文件夹
3.【编辑】点击对应文件夹的‘编辑’按钮后,变成input输入形式,点击对号确认后实现修改,点击‘取消’,退出编辑模式。
4.【缩略】文件夹名称过长时,显示缩略效果。
看完效果让我们开始一步步实现吧:
二、实现基础资源树样式
1.el-tree和el-table实现联动
(1)el-tree和el-table调接口显示数据
使用到的两个接口分别是:listKnowledge, treeslect
// 查询应急知识 列表
export function listKonwledge(query) {
return request({
url: "/konwledge/info/list",
method: "get",
params: query
});
}
// 查询文件下拉树结构
export function treeselect() {
return request({
url: "/knowledge/file/treeselect",
method: "get"
});
}
接口返回的数据如下:
data() {
return {
// 应急知识 表格数据
konwledgeList: [],
total:'',
//文件树
fileOptions: undefined,
defaultProps: {
children: "children",
label: "label",
},
}
}
created() {
// 获取table数据
this.getList();
// 获取树列表
this.getTreeselect();
},
methods: {
// 查询列表
getList() {
listKonwledge(this.queryParams).then((response) => {
this.konwledgeList = response.rows;
this.total = response.total;
});
},
// 查询树结构
getTreeselect() {
treeselect().then((response) => {
this.fileOptions = response.data;
console.log(response.data);
});
},
}
(2)实现tree和table两者联动
思路:对el-tree添加节点点击事件@node-click="handleNodeClick",并在该方法中获取节点的id,并作getList() 查询操作,从而实现两者联动
// tree节点单击事件
handleNodeClick(data) {
console.log(data, "handlenodeclick获取的数据,包含id;children;label");
this.queryParams.parentId = data.id;
this.getList();
},
全部完整代码如下:
<div class="tree-container">
<el-col :span="6" :xs="24">
<el-tree
:data="fileOptions"
:props="defaultProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
node-key="id"
default-expand-all
highlight-current
@node-click="handleNodeClick"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>
<!-- 正常情况 -->
<span v-if="data.id != operationVis">
<span>
{
{ node.label }}
</span>
<span style="margin-left: 20px">
<el-button type="text" size="mini">
<i class="el-icon-edit"></i>
</el-button>
<el-button type="text" size="mini">
<i class="el-icon-delete" style="color: red"></i>
</el-button>
</span>
</span>
</span>
</span>
</el-tree></el-col
>
<el-col :span="18" :xs="24">
<el-table
v-loading="loading"
:data="konwledgeList"
@selection-change="handleSelectionChange"
stripe
class="tableBox"
height="480"
:default-sort="{ prop: 'uploadTime', order: 'descending' }"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="序号"
align="center"
type="index"
width="50"
/>
<el-table-column
label="文件名称"
align="center"
prop="fileName"
width="300"
>
<template slot-scope="scope">
<span style="margin-left: 20px">
{
{ scope.row.fileName }}
</span>
</template>
</el-table-column>
<el-table-column
label="上传时间"
align="center"
prop="uploadTime"
width="130"
>
<template slot-scope="scope">
<span>{
{
parseTime(scope.row.uploadTime, "{y}年{m}月{d}日 {h}:{i}:{s}")
}}</span>
</template>
</el-table-column>
<el-table-column
label="上传人"
align="center"
prop="uploadPerson"
width="120"
/>
<el-table-column
label="上一级文件夹"
align="center"
prop="parentName"
/>
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button size="mini" type="text" @click="rename(scope.row)"
>重命名</el-button
>
<el-button
size="mini"
type="text"
@click="moveToOther(scope.row)"
>移动</el-button
>
<el-button
size="mini"
type="text"
@click="handleDelete(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
layout="total, prev, pager, next"
/>
</el-col>
</div>
至此的效果如下:
2.添加文件前的文件夹图标
分析:A.最外部的全部前面有一个定位图标;全部的id=100
B.如果文件夹节点是包含子节点的,那么就是文件夹图标;
C.如果资源是叶子节点,那么就是文件图标。
只需要在el-tree的span中添加如下代码
<span
><i
class="el-icon-location"
style="margin-right: 14px"
v-if="data.id == 100 ? true : false"
></i>
<i
class="el-icon-folder-opened"
style="margin-right: 14px"
v-else-if="data.children != null ? true : false"
></i>
<i
class="el-icon-folder"
style="margin-right: 14px"
v-else
></i
></span>
三、实现资源树修改功能
1.实现思路
设计思路:
前端效果分成两种情况:A.文件资源树正常情况:label展示文件树节点名称;后面有编辑和删除的图标按钮
B.文件资源树编辑情况:input展示节点并实现可编辑输入效果;后面有确定和取消的图标按钮。
2.开发编辑情况时的前端效果
(1)实现文件资源树编辑情况
注释掉之前的span 文件资源树的正常情况,
<span>
<el-input
style="width: 120px"
size="mini"
>
</el-input>
<span
style="margin-left: 20px"
>
<el-button
type="text"
size="mini"
@click="() => sureChange(data)"
>
<i
class="el-icon-circle-check"
style="color: rgb(19, 206, 102)"
></i>
</el-button>
<el-button
type="text"
size="mini"
@click="() => chancelChange(node, data)"
>
<i class="el-icon-circle-close" style="color: gray"></i>
</el-button>
</span>
</span>
(2)添加input的输入绑定
但是我们会发现这时的input是无法输入的,需要使用:value绑定,而不是使用:model
并且添加input输入的事件,从而实现输入绑定
<el-input
style="width: 120px"
size="mini"
ref="inputVal"
:value="data.label"
@focus="focus($event)"
@input="(a) => inp(a, data)"
>
</el-input>
focus(event) {},
inp(value, data) {
data.label = value;
},
至此,我们实现了这样的效果,可以在input中修改
3.实现编辑效果
(1)区分被选中编辑的节点
我们这一步需要结合两种情况,实现点击编辑按钮,对应的节点变成可编辑情况,但是未选中的节点不变
A. 如何区分哪个节点是选中的呢??
方法:记录点击选中的节点的id,对于每个节点data.id都与此记录的临时operationVis做对比即可。
B. 在何处记录这个选中的节点??
在点击编辑按钮事件editFile时,记录选中节点 this.operationVis = data.id;
// 编辑按钮
editFile(data) {
this.operationVis = data.id;
},
C. 如何区分一般情况和可编辑情况?
在点击编辑时添加标记data.id != operationVis,并在取消或者确认修改之后 this.operationVis = "";
<!-- 正常情况 -->
<span v-if="data.id != operationVis">
.....
</span>
</span>
<!-- 编辑情况 -->
<span v-else>
....
</span>
el-tree的完整代码如下:
<el-tree
:data="fileOptions"
:props="defaultProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
node-key="id"
default-expand-all
highlight-current
@node-click="handleNodeClick"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>
<span
><i
class="el-icon-location"
style="margin-right: 14px"
v-if="data.id == 100 ? true : false"
></i>
<i
class="el-icon-folder-opened"
style="margin-right: 14px"
v-else-if="data.children != null ? true : false"
></i>
<i
class="el-icon-folder"
style="margin-right: 14px"
v-else
></i
></span>
<!-- 正常情况 -->
<span v-if="data.id != operationVis">
<span>
{
{ node.label }}
</span>
<span style="margin-left: 20px">
<el-button
type="text"
size="mini"
@click="() => editFile(data)"
>
<i class="el-icon-edit"></i>
</el-button>
<el-button
type="text"
size="mini"
@click="() => remove(node, data)"
>
<i class="el-icon-delete" style="color: red"></i>
</el-button>
</span>
</span>
<!-- 编辑情况 -->
<!-- -->
<span v-else>
<el-input
style="width: 120px"
size="mini"
ref="inputVal"
:value="data.label"
@focus="focus($event)"
@input="(a) => inp(a, data)"
>
</el-input>
<span
style="margin-left: 20px"
v-if="data.id != 100 ? true : false"
>
<el-button
type="text"
size="mini"
@click="() => sureChange(data)"
>
<i
class="el-icon-circle-check"
style="color: rgb(19, 206, 102)"
></i>
</el-button>
<el-button
type="text"
size="mini"
@click="() => chancelChange(node, data)"
>
<i class="el-icon-circle-close" style="color: gray"></i>
</el-button>
</span>
</span>
</span>
</span> </el-tree
>
(2)实现编辑的确认
接口:
// 更新文件夹名称
export function updateKonwledgeFile(data) {
return request({
url: "/knowledge/file",
method: "put",
data: data
});
}
sureChange(data) {
console.log(data, "点击确认修改");
const params = {
fileName: data.label,
fileId: data.id,
};
debugger;
updateKonwledgeFile(params).then((response) => {
if (response.code == 200) {
this.msgSuccess("修改成功");
this.operationVis = "";
this.getTreeselect();
}
this.folderFlag = false;
});
},
至此实现了编辑功能,效果如下:
4. 实现取消和删除功能
(1)取消功能的实现
<el-button
type="text"
size="mini"
@click="() => chancelChange(node, data)"
>
<i class="el-icon-circle-close" style="color: gray"></i>
</el-button>
// 取消修改按钮
chancelChange() {
this.operationVis = false;
},
(2)删除功能实现
<el-button
type="text"
size="mini"
@click="() => remove(node, data)"
>
<i class="el-icon-delete" style="color: red"></i>
</el-button>
// 文件夹节点删除
remove(node, data) {
this.formFolder.parentId = data.id;
console.log(data, node, "remove节点获取到的信息");
this.handleFolderDelete(data.id, data.label);
},
四、其他前端效果
1.修改el-tree默认下拉图标的位置
一般下拉框是在左侧,如果实在想要修改位置,可以使用如下代码。个人觉得并不好看,哈哈
// 修改下拉图标的位置
::v-deep .el-tree-node__expand-icon {
position: absolute;
right: 2%;
}
::v-deep .el-tree-node__label {
padding-left: 15px;
}
2.名称过长缩略显示
对于正常情况需要分情况:A.字符串长度短:正常显示
B.字符串长度过长,使用el-popover 并截取前十个字符显示
3.部分节点有编辑删除功能
其实‘全部’节点不可编辑,因此也需要使用v-if判断是否为‘全部’节点v-if="data.id != 100 ? true : false"
<!-- 正常情况 -->
<span v-if="data.id != operationVis">
<el-popover
placement="top-start"
trigger="hover"
v-if="node.label.length > 8"
>
<div>{
{ node.label }}</div>
<span slot="reference">
<a>{
{ node.label.substr(0, 7) + "..." }}</a></span
>
</el-popover>
<span v-else>
{
{ node.label }}
</span>
<span
style="margin-left: 20px"
v-if="data.id != 100 ? true : false"
>
<el-button
type="text"
size="mini"
@click="() => editFile(data)"
>
<i class="el-icon-edit"></i>
</el-button>
<el-button
type="text"
size="mini"
@click="() => remove(node, data)"
>
<i class="el-icon-delete" style="color: red"></i>
</el-button>
</span>
</span>
五、类比实现el-table单元格的编辑功能
点击重命名按钮触发修改模式
实现原理一致,附代码,大家可以自行学习。
<el-table-column
label="文件名称"
align="center"
prop="fileName"
width="300"
>
<!-- show-overflow-tooltip="true" -->
<template slot-scope="scope">
<span style="margin-left: 20px">
<!-- 未编辑情况 -->
<el-popover
placement="top-start"
trigger="hover"
v-show="
scope.row.id != renameId && scope.row.fileName.length > 15
"
>
<div>{
{ scope.row.fileName }}</div>
<span slot="reference" @click="handleDownload(scope.row)">
<a style="color: rgb(24, 144, 255)">{
{
scope.row.fileName.substr(0, 14) + "..."
}}</a></span
>
</el-popover>
<span
v-show="
scope.row.id != renameId && scope.row.fileName.length < 15
"
>
<el-button type="text" @click="handleDownload(scope.row)">{
{
scope.row.fileName
}}</el-button>
</span>
<!-- 修改情况 -->
<span v-show="scope.row.id == renameId"
><el-input
v-model="scope.row.fileName"
@input="(a) => inpFile(a, scope.row)"
style="width: 210px"
type="small"
></el-input>
<el-button
type="text"
size="mini"
style="margin-left: 8px"
@click="() => changeFile(scope.row)"
>
<i
class="el-icon-circle-check"
style="color: rgb(19, 206, 102)"
></i>
</el-button>
<el-button type="text" size="mini">
<i
class="el-icon-circle-close"
style="color: gray"
@click="() => cancelFile(scope.row)"
></i> </el-button
></span>
</span>
</template>
</el-table-column>
对应资源源码下载:可编辑el-tree样式功能修改:修改icon、可编辑input、修改下拉展开icon位置-Javascript文档类资源-CSDN下载