Vue树节点的增加和删除

简介: Vue树节点的增加和删除

在树节点上填上按钮结合Vue和ElementUI

  1. span标签代表按钮

==expand-on-click-node==:是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点。
==show-checkbox node-key==:展示复选框,以及复选框的id。
==:default-expanded-keys==="expanded"冒号代表是v-bind的缩写,是为了动态绑定数据,这个属性说明默认打开第一个树节点,因为绑定数据是一个变量,需要在data数据方法中写好

    data() {
        return {
          category:{name:"",parentCid:0,catLevel:0,showStatus:1,sort:0},
          dialogVisible:false,
          menus: [],
          expanded:[],
          defaultProps: {
            children: 'children',
            label: 'name'
          }
        };
      },

下面是树的点击按钮

<el-tree :data="menus" :props="defaultProps" :expand-on-click-node="false" show-checkbox node-key="catId" :default-expanded-keys="expanded">
       <span class="custom-tree-node" slot-scope="{ node, data }">
           <span>{{ node.label }}</span>
           <span>
           <!--这里判断了一下层级小于等于2的时候显示添加,反之-->
             <el-button
               v-if="node.level<=2"
               type="text"
               size="mini"
               @click="() => append(data)">
               添加
             </el-button>
             <!--这里判断了没有子节点的话才显示删除-->
             <el-button
               v-if="node.childNodes.length==0"
               type="text"
               size="mini"
               @click="() => remove(node, data)">
               删除
             </el-button>
           </span>
         </span>
</el-tree>
  1. 在methods的方法体中写上请求后台的方法。

这里的==this.$http==方法是封装请求后台的,详细见项目中的httpRequest.js文件。

      methods: {
        // 树节点的添加
        append(data) {
          console.log("append"+data)
          this.dialogVisible = true;
          //点击当前的id
          this.category.parentCid = data.catId;
          // 得到下一个的层级先乘1是防止是字符串
          this.category.catLevel = data.catLevel*1 + 1;
        },
        //添加的方法
        addCategory(){
          console.log("提交的三级分类的数据是:"+this.category.name)
          this.$http({
            url: this.$http.adornUrl('/product/category/save'),
            method: 'post',
            data: this.$http.adornData(this.category, false)
          }).then(({data}) => {
            this.$message({
              message: '恭喜你,这是一条成功消息',
              type: 'success'
            });
            //关闭窗口
            this.dialogVisible = false
            //刷新出新的菜单
            this.getMenus();
            //设置需要默认展开的菜单
            this.expanded=[this.category.parentCid];
          })
        },
        // 树节点的删除
        remove(node, data) {
          console.log("remove"+node,data);
          var ids = [data.catId];
          this.$confirm(`是否删除[${data.name}]菜单?`, '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.$http({
              url: this.$http.adornUrl('/product/category/delete'),
              method: 'post',
              data: this.$http.adornData(ids, false)
            }).then(({data}) => {
              this.$message({
                message: '恭喜你,这是一条成功消息',
                type: 'success'
              });
              //刷新出新的菜单
              this.getMenus();
              //删除之后默认展开当前的菜单
              this.expanded=[node.parent.data.catId];
            })
          }).catch(() => {
            this.$message({
              type: 'info',
              message: '已取消删除'
            });
          });
        },
      },
  1. 先写删除的方法,删除方法在这写的是逻辑删除,并非真正的删除,结合Mybatisplus的使用

1).逻辑删除的配置首先在yml中配置:

mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml
#  主键自增
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1 #代表删除(不显示)
      logic-not-delete-value: 0 #没删除(显示)

2).配置好之后还要在实体类上加上

    /**
     * 是否显示[0-不显示,1显示]
     */
    //逻辑删除的注解,这里发现,数据库的设置与配置文件的是相反的,就可以在注解后面加上value和delval两个来替换下。
    @TableLogic(value = "1",delval = "0")
    private Integer showStatus;

3)逻辑删除的语法

 @Override
    public void removeMenuByIds(List<Long> asList) {
        //TODO 检查当前删除的菜单,是否被别的地方引用
        baseMapper.deleteBatchIds(asList);
    }

4)想看打印出来的日志,在yml文件中配置debug

logging:
  level:
    com.atdada.dadamall: debug
  1. 在做新增树节点的时候,需要一个弹窗
<!-- dialogVisible值为true是打开窗口,反之...:close-on-click-modal="false"鼠标点击其他地方不会关闭窗口,注意他是一个boolen值,要绑定加: 冒号 -->
     <el-dialog
       title="提示"
       :visible.sync="dialogVisible"
       width="30%" :close-on-click-modal="false">
       <el-form :model="category">
         <el-form-item label="分类名称">
           <el-input v-model="category.name" autocomplete="off"></el-input>
         </el-form-item>
       </el-form>
       <span slot="footer" class="dialog-footer">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="addCategory">确 定</el-button>
       </span>
     </el-dialog>

5.再点击@click="() => append(data)按钮的时候会触发一个函数,在append中把:expand-on-click-node="true"就打开窗口了。
此函数是在methods: {}中的。并且在点击的时候要拿到当前的id和要添加这一级的层级+1.也要在data(){}中把变量写好
category:{name:"",parentCid:0,catLevel:0,showStatus:1,sort:0},

        // 树节点的添加
        append(data) {
          console.log("append"+data)
          this.dialogVisible = true;
          //点击当前的id
          this.category.parentCid = data.catId;
          // 得到下一个的层级先乘1是防止是字符串
          this.category.catLevel = data.catLevel*1 + 1;
        },

6.在弹出窗口之后点击确定绑定@click="addCategory"函数。

        //添加的方法
        addCategory(){
          console.log("提交的三级分类的数据是:"+this.category.name)
          this.$http({
            url: this.$http.adornUrl('/product/category/save'),
            method: 'post',
            data: this.$http.adornData(this.category, false)
          }).then(({data}) => {
            this.$message({
              message: '恭喜你,这是一条成功消息',
              type: 'success'
            });
            //关闭窗口
            this.dialogVisible = false
            //刷新出新的菜单
            this.getMenus();
            //设置需要默认展开的菜单
            this.expanded=[this.category.parentCid];
          })
        },

7.后台的保存方法,已经有逆向工程自动生成

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody CategoryEntity category){
        categoryService.save(category);

        return R.ok();
    }

8.再做修改的时候,可以把添加的按钮复制下来,哪些节点可能都需要修改,所以就不用判断了。紧接着就需要写edit的函数了;

        <el-button
               type="text"
               size="mini"
               @click="() => edit(data)">
               修改
        </el-button>

9.因为修改的时候是根据id来修改的,所以也要把catId写到

 category:{name:"",parentCid:0,catLevel:0,showStatus:1,sort:0,catId:null},

10.还有再更改的时候,因为添加和编辑用的都是同一个对话框,所以在添加的时候给某个值赋值为add,更改就赋值为edit,
也要在,在这里插入图片描述
11.判断是更改还是新增,就应该在修改和新增的弹窗事件的时候分别给这个标识位赋值,然后去判断当前的操作是更改还是添加

this.dialogType = "edit";//放到更改的弹窗位置
this.dialogType = "add";
submitData(){
          if (this.dialogType == "add"){
            this.addCategory();
          }
          if (this.dialogType == "edit"){
            this.editCategory();
          }
        },

同时想修改上面的标题的话需要把title加一个双向绑定事件,在from表单中写上:title="title",然后再data(){}中加入这个变量,最后也是在更改和新增的弹窗方法上写上this.title="添加/修改",下面是修改的弹窗:。

        edit(data){
          this.title="修改";
          this.dialogType = "edit";
          console.log("要更改的数据"+data)
          this.dialogVisible = true ;//打开窗口
          this.$http({
            url:this.$http.adornUrl(`/product/category/info/${data.catId}`),
            method:"get",
          }).then(({data})=>{
            console.log("要回显的数据:"+data)
            this.category.name = data.data.name;
            this.category.catId = data.data.catId;
            this.category.icon = data.data.icon;
            this.category.productUnit = data.data.productUnit;
            this.category.parentCid = data.data.parentCid;
          });
          //这样的回显是不合理的,容易出现脏读的现象,所以还是要每次请求后台来查询出最新的数据
          // this.category.name = data.name;
          // this.category.catId = data.catId;
        },

12.数据回显之后就可以做更改操作了

        editCategory(){
          //因为有的值不需要传,所以可以把需要传递的值放到{}里,如果不这样就把所有数据回显出来
          var {catId,name,icon,productUnit} = this.category;
          var data1 = {catId:catId,name: name,icon: icon,productUnit: productUnit};
          var data = {catId,name,icon,productUnit};//key  value一样的话 也可以这样写
          this.$http({
            url:this.$http.adornUrl("/product/category/update"),
            method:"post",
            data:this.$http.adornData(data,false)
          }).then(({data})=>{
            this.$message({
              message: '恭喜你,这是一条成功消息',
              type: 'success'
            });
            //关闭窗口
            this.dialogVisible = false
            //刷新出新的菜单
            this.getMenus();
            //设置需要默认展开的菜单
            this.expanded=[this.category.parentCid];
          });
        },

13.此时会发现修改之后,再次点击添加发现添加窗口还是有值的这是因为没有把字段置空在这里插入图片描述
14.draggable它是tree的属性,写上它可以拖拽节点的位置。

<el-tree :data="menus" :props="defaultProps" :expand-on-click-node="false" show-checkbox node-key="catId" :default-expanded-keys="expanded" draggable></<el-tree>

15.判断哪个层级是能拖拽的,那个层级是不能拖拽的,这里默认最多3层级

        //判断是否能够拖拽
        allowDrop(draggingNode, dropNode, type) {
          //1.被拖动的当前节点以及所在的父节点总层数不能大于3
          //1)被拖动的当前节点的总层数
          console.log("拖拽方法:",draggingNode, dropNode, type)
          var level = this.countNodeLevel(draggingNode.data);
          //当前正在拖动的节点+父节点所在的深度不大于3即可
          let deep = (this.maxLevel - draggingNode.data.catLevel)+1;
          console.log("深度:",deep)
          //拖到节点里面是相加关系
          if (type == "inner"){
            return (deep + dropNode.level) <= 3;
          }else{
            return (deep + dropNode.parent.level) <= 3;
          }
        },
        countNodeLevel(node){//当前节点
          //找到所有子节点,求出最大深度
          //先判断当前节点是否有子节点
          if(node.children !=null && node.children.length >0){
            //进来的话说明有子节点,开始遍历所有的子节点
              for(let i = 0;i<node.children.length;i++){
                //如果当前层级大于设置的0的时候就给他交换值,相当于自己调用自己的一个递归了
                if(node.children[i].catLevel > this.maxLevel){
                  this.maxLevel = node.children[i].catLevel;
                }
                this.countNodeLevel(node.children[i]);
              }
          }
        },
相关文章
|
3天前
|
JavaScript 前端开发
vue动态添加style样式
vue动态添加style样式
|
2天前
|
JavaScript API
vue学习(13)监视属性
vue学习(13)监视属性
10 2
|
2天前
|
JavaScript
vue 函数化组件
vue 函数化组件
|
2天前
|
JavaScript 前端开发
vue学习(15)watch和computed
vue学习(15)watch和computed
9 1
|
2天前
|
JavaScript
vue学习(14)深度监视
vue学习(14)深度监视
10 0
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
1037 0
|
3天前
|
JavaScript
vue中watch的用法
vue中watch的用法
|
3天前
|
JavaScript 前端开发
Vue项目使用px2rem
Vue项目使用px2rem
|
9天前
|
JavaScript 前端开发
vue学习(6)
vue学习(6)
30 9
|
9天前
|
JavaScript 开发者
vue学习(5)
vue学习(5)
24 7