问题
最近有这样的需求,需要对elementUI Tree树节点做某些操作,比如编辑、删除、上移或下移操作,并且需要在节点后展示,官网中,没有好的直接实现方式,所以就自己弄弄。
实现功能
点击某节点,出现操作图标,默认不出现的
点击操作图标,实现具体操作,比如:上下移动功能
第一节点不能出现上移图标,最后节点不能出现下移图标
难点
上下移动操作,肯定需要找到两个节点数据,再传给服务端,拿当前节点好获取,但上一节点或下一节点呢。
实现
代码
html部分
<el-tree class="filter-tree" :data="data2" accordion
:highlight-current=true
:draggable=true
:props="defaultProps"
:default-expand-all=false
:check-on-click-node=true
:filter-node-method="filterNode"
@node-click="nodeClick" ref="tree2">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<!-- 1、 节点被选中后才展示-->
<span v-if='node.isCurrent == true && node.level == 1' class="el-tree-span">
<i class="el-icon-delete el-tree-i" @click="deleteGroup(node, data)"> </i>
<!-- 2、通过类型判断是上移还是下移,传入当前节点数据 -->
<i v-if='node.previousSibling !== null' class="el-icon-top el-tree-i" @click="moveGroup('up',node, data)"> </i>
<!-- 3、通过v-if -->
<i v-if='node.nextSibling !== null && node.nextSibling !== undefined ' class="el-icon-bottom" @click="moveGroup('down',node, data)"> </i>
</span>
</span>
</el-tree>
js部分
//节点移动
moveGroup (type, node, data) {
var self = this;
let frontId = ''
let afterId = ''
if (type == 'up') {
afterId = node.previousSibling.data.id
frontId = node.data.id
} else if (type == 'down') {
frontId = node.nextSibling.data.id
afterId = node.data.id
}
this.$post("http://" + self.$serviceNew + "/projectGroup/move", {
frontId: frontId,
afterId: afterId
}).then(function (resp) {
self.$message({
message: resp.message,
type: "success"
});
self.getProjectGroup(self.ProjectGroupForm.projectId);
}).catch(function (error) {
self.$message({
message: "请求异常!",
type: "error"
});
});
},
1、源码中第一步,首先实现在做点击操作时,自动展示操作图标
树组件中,判断某节点是否选中时有个属性叫 isCurrent,表示当前节点是否选择,那么如果选中了我们就展示操作图标。
并且由于我们分组中只管一级节点,所以加了个节点等级为一级才展示。
2、源码中第二步,实现具体移动操作
通过类型判断是上移还是下移,传入当前节点数据,节点中有个属性叫previousSibling和*nextSibling*,花费了好半天才找到竟然还有这样的属性,他表示该节点的前一节点和后一节点,这样的话就好做了,通过这两个属性就可以拿到前一节点数据和后一节点中数据。
从 moveGroup方法中可以看出我们拿到两个节点的id值,这也是服务端返回的,传给服务端,让服务端去做移动操作,然后在刷新下tree节点。
3、源码中第三步,实现第一节点不能出现上移图标,最后节点不能出现下移图标
通过v-if判断,如果当前节点的前一节点 **previousSibling **为空,就表示该节点在最上边,就不需要展示上移图标,如果当前节点的后一节点 *****nextSibling*** **为空,就表示该节点在最下边,就不需要展示下移图标。
实现效果
服务端接口
服务端实现其实就是数据库中有个 排序的字段ordercode,我们针对这个字段来变换他的值,达到更换顺序功能
@PostMapping("/move")
@ResponseBody
public ResultBean<Object> ReplacementSteps(@RequestParam("frontId") Integer frontId, @RequestParam("afterId") Integer afterId){
try {
logger.info("/projectGroup/move POST 方法被调用!!");
if (null != frontId && null != afterId) {
ProjectGroupBean frontBean = projectGroupBll.getProjectGroupById(frontId);
ProjectGroupBean afterIdBean = projectGroupBll.getProjectGroupById(afterId);
if(frontBean != null && afterIdBean != null){
Integer id = frontBean.getOrderCode();
frontBean.setOrderCode(afterIdBean.getOrderCode());
afterIdBean.setOrderCode(id);
if(projectGroupBll.update(frontBean) && projectGroupBll.update(afterIdBean)){
return ResultBean.success("移动分组成功!!");
}
}else{
return ResultBean.success("移动的分组不存在!");
}
}
else {
return ResultBean.success("移动的分组编号不能为空!");
}
return null;
} catch (Exception e) {
logger.error("切换用例步骤异常:{" + e + "}");
return ResultBean.failed("切换用例步骤异常!",e.getMessage());
}
}
总结
关键点就是我们通过previousSibling和nextSibling 很方便拿到同级节点的前一个和后一个节点数据。
不好的地方没能实现鼠标放上去就出现图标,而是需要点击。