zoukankan      html  css  js  c++  java
  • vue可拖拽树

     注:自用,一些样式其他人可能没有

    <!-- Vue SFC -->
    <template>
      <div class="container bxs">
        <div class="ct-inner bxs">
          <div class="ct-inner-fiexd w">
            <el-input placeholder="请输入关键词" suffix-icon="el-icon-search" v-model="filterText"></el-input>
            <div class="w clearfix tc mt10">
              <el-button class="fll" type="primary" plain size="mini">刷新</el-button>
              <el-button type="primary" plain size="mini" @click="unFoldAll">全部展开</el-button>
              <el-button class="flr" type="primary" plain size="mini" @click="collapseAll">全部收起</el-button>
            </div>
          </div>
          <div class="ct-inner-content h">
            <!-- show-checkbox 是否展示多选框 -->
            <!-- :check-on-click-node="true" 点击文本内容是否选中 -->
            <el-tree
              v-if="openOrNot"
              :data="treeData"
              node-key="id"
              :default-expand-all="defaultExpand"
              :expand-on-click-node="false"
              @node-click="handleLeftclick"
              @node-drag-start="handleDragStart"
              @node-drag-enter="handleDragEnter"
              @node-drag-leave="handleDragLeave"
              @node-drag-over="handleDragOver"
              @node-drag-end="handleDragEnd"
              @node-drop="handleDrop"
              @node-contextmenu="rightClick"
              :filter-node-method="filterNode"
              draggable
              :allow-drop="allowDrop"
              :allow-drag="allowDrag"
              ref="tree"
            >
              <span class="slot-t-node span-ellipsis" slot-scope="{ node, data }">
                <span class="span-ellipsis-inner" v-show="!data.isEdit">
                  <!-- <el-tooltip class="item" effect="dark" :content="node.label" placement="right"> -->
                  <span class="span-ellipsis">
                    <span
                      class="span-ellipsis"
                      :class="[(selectTreeData&&data.id==selectTreeData.id)? 'slot-t-node--label' : '']"
                      style="vertical-align:middle;"
                    >
                      <i class="iconfont jxintegral-fill"></i>
                      {{node.label}}
                    </span>
                  </span>
                  <!-- </el-tooltip> -->
                </span>
                <!-- autofocus -->
                <span v-show="data.isEdit">
                  <el-input
                    class="slot-t-input"
                    style="height:28px;"
                    size="mini"
                    v-model="data.label"
                    :ref="'slotTreeInput'+data.id"
                    @blur.stop="NodeBlur(node,data)"
                    @keydown.native.enter="NodeBlur(node,data)"
                  ></el-input>
                </span>
              </span>
            </el-tree>
    
            <el-card class="box-card" ref="card" v-show="menuVisible">
              <div @click="addSameLevelNode()" v-show="firstLevel">
                <i class="el-icon-circle-plus-outline"></i>
                <span class="ml10">同级增加</span>
              </div>
    
              <div class="add" @click="addChildNode()">
                <i class="el-icon-circle-plus-outline"></i>
                <span class="ml10">子级增加</span>
              </div>
    
              <div class="delete" @click="deleteNode()">
                <i class="el-icon-remove-outline"></i>
                <span class="ml10">删除节点</span>
              </div>
    
              <div class="edit" @click="editNode()">
                <i class="el-icon-edit"></i>
                <span class="ml10">修改节点</span>
              </div>
            </el-card>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    import axios from "axios";
    export default {
      name: "PersonManageLf",
      components: {},
      data() {
        return {
          openOrNot: true, //展开收缩dom挂载切换
          defaultExpand: true, //默认全部展开
          eleId: "",
    
          isShow: false,
    
          currentData: "",
    
          currentNode: "",
    
          menuVisible: false,
    
          firstLevel: false,
    
          filterText: "",
    
          maxexpandId: 4,
    
          treeData: [
            {
              id: 1,
    
              label: "一级 1",
    
              isEdit: false,
    
              children: [
                {
                  id: 4,
    
                  label: "二级 1-1",
    
                  isEdit: false,
    
                  children: [
                    {
                      id: 9,
    
                      label:
                        "三级 1-1-1呜呜呜呜呜呜呜呜无无无无无无无无无无无无无无无无无",
    
                      isEdit: false,
                    },
                    {
                      id: 10,
    
                      label: "三级 1-1-2",
    
                      isEdit: false,
                    },
                  ],
                },
              ],
            },
            {
              id: 2,
    
              label: "一级 2",
    
              isEdit: false,
    
              children: [
                {
                  id: 5,
    
                  label: "二级 2-1",
    
                  isEdit: false,
                },
                {
                  id: 6,
    
                  label: "二级 2-2",
    
                  isEdit: false,
                },
              ],
            },
            {
              id: 3,
    
              label: "一级 3",
    
              isEdit: false,
    
              children: [
                {
                  id: 7,
    
                  label: "二级 3-1",
    
                  isEdit: false,
                },
                {
                  id: 8,
    
                  label: "二级 3-2",
    
                  isEdit: false,
    
                  children: [
                    {
                      id: 11,
    
                      label: "三级 3-2-1",
    
                      isEdit: false,
                    },
                    {
                      id: 12,
    
                      label: "三级 3-2-2",
    
                      isEdit: false,
                    },
                    {
                      id: 13,
    
                      label: "三级 3-2-3",
    
                      isEdit: false,
                    },
                  ],
                },
              ],
            },
          ],
          treeDataCopy: "", //   拖拽结束后验证后不可拖拽
          defaultProps: {
            children: "children",
    
            label: "label",
          },
          selectTreeNode: "", //选中的树节点,内含父节点
          selectTreeData: "", //选中的树data
          newAddTreeObjs: {}, //新增节点储存对象
          nowAddTreeNodeid: "", //当前新增节点id
        };
      },
      methods: {
        // 全部展开
        unFoldAll() {
          let self = this;
          // 将没有转换成树的原数据
          let list = this.treeData;
          for (let i = 0; i < list.length; i++) {
            // 将没有转换成树的原数据设置key为... 的展开
            self.$refs.tree.store.nodesMap[list[i].id].expanded = true;
          }
        },
        // 全部折叠
        collapseAll() {
          let self = this;
          // 将没有转换成树的原数据
          let list = this.treeData;
          for (let i = 0; i < list.length; i++) {
            self.$refs.tree.store.nodesMap[list[i].id].expanded = false;
          }
        },
        renderContent(h, { node, data, store }) {
          console.log(node.label);
          console.log(data);
          console.log(store);
          return (
            <div style="display:inline-block;">
              <span style="">{node.label}</span>
            </div>
          );
        },
        open() {
          this.defaultExpand = !this.defaultExpand;
          this.openOrNot = false;
          setTimeout(() => {
            this.openOrNot = true;
          }, 10);
        },
    
        NodeBlur(Node, data) {
          // debugger;
    
          console.log(Node, data);
    
          if (data.label.length === 0) {
            this.$message.error("菜单名不可为空!");
            return false;
          } else {
            if (data.isEdit) {
              this.$set(data, "isEdit", false);
              console.log(data.isEdit);
            }
            this.$nextTick(() => {
              this.$refs["slotTreeInput" + data.id].$refs.input.focus();
            });
          }
        },
    
        // 查询
    
        filterNode(value, data) {
          if (!value) return true;
    
          return data.label.indexOf(value) !== -1;
        },
    
        handleDragStart(node, ev) {
          console.log(this.treeData, "");
          console.log("drag start", node);
          //   如果要阻止拖拽
          //   if(node.childNodes.length>0){
          //       console.log("有子节点不能移动")
          //       ev.preventDefault();
          //       return;
          //   }
        },
    
        handleDragEnter(draggingNode, dropNode, ev) {
          console.log("tree drag enter: ", dropNode.label);
        },
    
        handleDragLeave(draggingNode, dropNode, ev) {
          console.log("tree drag leave: ", dropNode.label);
        },
    
        handleDragOver(draggingNode, dropNode, ev) {
          console.log("tree drag over: ", dropNode.label);
        },
    
        handleDragEnd(draggingNode, dropNode, dropType, ev) {
          console.log("tree drag end: ", dropNode && dropNode.label, dropType);
        },
    
        handleDrop(draggingNode, dropNode, dropType, ev) {
          console.log("tree drop: ", dropNode.label, dropType);
          //   拖拽结束后验证后不可拖拽
          //    console.log(this.treeData,'树')
          //    this.treeData=JSON.parse(JSON.stringify(this.treeDataCopy));
        },
    
        allowDrop(draggingNode, dropNode, type) {
          console.log(dropNode.data)
          if (dropNode.data.label === "二级 3-1") {
            return type !== "inner";
          } else {
            return true;
          }
        },
    
        allowDrag(draggingNode) {
          return draggingNode.data.label.indexOf("三级 3-2-2") === -1;
        },
    
        // 鼠标右击事件
    
        rightClick(MouseEvent, object, Node, element) {
          //   debugger;
          console.log(Node);
    
          this.currentData = object;
    
          this.currentNode = Node;
    
          if (Node.level === 1) {
            this.firstLevel = true;
          } else {
            this.firstLevel = false;
          }
    
          this.menuVisible = true; // let menu = document.querySelector('#card')
    
          // /* 菜单定位基于鼠标点击位置 */
    
          // menu.style.left = event.clientX + 'px'
    
          // menu.style.top = event.clientY + 'px'
    
          document.addEventListener("click", this.foo);
    
          // console.log(event.clientY);
          this.$refs.card.$el.style.left = event.clientX + 40 - 250 + "px";
    
          this.$refs.card.$el.style.top = event.clientY + 10 - 165 + "px";
        },
    
        // 鼠标左击事件
    
        handleLeftclick(data, node) {
          // console.log(data,'选中的节点')
          this.selectTreeNode = node;
          this.selectTreeData = data;
          this.foo(data.id, true);
        },
        //判断是否为新增id,且新增id是否为真id
        sureNewOrOld(id) {
          //1 表明是旧id,2表示新id,3表示id未返回
          id = id + "";
          let arrs = id.split("-");
          let newAddTreeObjs = this.newAddTreeObjs;
          if (arrs[0] == "xzjd") {
            console.log(id);
            console.log(newAddTreeObjs);
            console.log(newAddTreeObjs[id]);
            let idData = newAddTreeObjs[id];
            if (idData.id != id) {
              return 2;
            } else {
              // 新增部门,请刷新列表获取信息!
              this.$message.warning("新增部门,请稍后操作!");
              this.selectTreeNode = "";
              this.selectTreeData = "";
              return 3;
            }
          } else {
            return 1;
          }
        },
    
        //  取消鼠标监听事件 菜单栏
    
        foo(id, havesure) {
          // havesure判断是否为左键点击
          let newAddTreeObjs = this.newAddTreeObjs;
          this.menuVisible = false; //  要及时关掉监听,不关掉的是一个坑,不信你试试,虽然前台显示的时候没有啥毛病,加一个alert你就知道了
          document.removeEventListener("click", this.foo);
          if (this.nowAddTreeNodeid) {
            this.nowAddTreeNodeid = "";
            return;
          }
          console.log("真正选中的节点");
          if (!havesure) {
            return;
          }
          let oldSure = this.sureNewOrOld(id);
          console.log(oldSure);
          if (oldSure == 2) {
          } else if (oldSure == 3) {
            return;
          } else {
            this.changeRightMess(id);
          }
          console.log();
        },
        // 刷新右侧信息
        changeRightMess(id) {
          this.$emit("sentFather", { id: id });
        },
    
        // 增加同级节点事件
    
        addSameLevelNode() {
          let id = Math.ceil(Math.random() * 1000);
          let timestamp = Date.parse(new Date());
          id = "xzjd-" + id + "-" + timestamp;
          console.log(id);
          var data = { id: id, label: "新增节点" };
          this.newAddTreeObjs[id] = data;
          this.nowAddTreeNodeid = id;
          this.$refs.tree.append(data, this.currentNode.parent);
        },
    
        // 增加子级节点事件
    
        addChildNode() {
          console.log(this.currentData);
          console.log(this.currentNode);
          // if (this.currentNode.level >= 3) {
          //   this.$message.error("最多只支持三级!");
          //   return false;
          // }
          let id = Math.ceil(Math.random() * 1000);
          let timestamp = Date.parse(new Date());
          id = "xzjd-" + id + "-" + timestamp;
          var data = { id: id, label: "新增节点" };
          this.newAddTreeObjs[id] = data;
          this.nowAddTreeNodeid = id;
          this.$refs.tree.append(data, this.currentNode);
        },
    
        // 删除节点
    
        deleteNode() {
          this.$refs.tree.remove(this.currentNode);
        },
    
        // 编辑节点
    
        editNode() {
          // debugger;
    
          if (!this.currentData.isEdit) {
            this.$set(this.currentData, "isEdit", true);
          }
        },
      },
    
      watch: {
        filterText(val) {
          this.$refs.tree.filter(val);
        },
      },
    
      mounted() {
        // this.test();
        //   拖拽结束后验证后不可拖拽
        // this.treeDataCopy=JSON.parse(JSON.stringify(this.treeData))
      },
    };
    </script>
    <style lang="scss"  scoped>
    .container {
      height: 95%;
      .ct-inner {
        height: 100%;
        position: relative;
        padding-top: 84px;
        .ct-inner-fiexd {
          position: absolute;
          left: 0;
          top: 0;
        }
        .ct-inner-content {
          // overflow: hidden;
            .text {
            font-size: 14px;
          }
          .add {
            cursor: pointer;
            margin-top: 10px;
          }
    
          .delete {
            margin: 10px 0;
            cursor: pointer;
          }
    
          .edit {
            margin-bottom: 10px;
    
            cursor: pointer;
          }
    
          .box-card {
            width: 140px;
    
            position: absolute;
    
            z-index: 1000;
          }
          .slot-t-node--label {
            background-color: #f5f7fa;
          }
        }
      }
    }
    .span-ellipsis {
      width: 100%;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      display: inline-block;
    }
    </style>
    <style >
    .el-tree {
      width: 100%;
      max-height: 95%;
      padding-bottom: 20px;
      overflow: auto;
    }
    .el-tree > .el-tree-node {
      display: inline-block;
      min-width: 100%;
    }
    .el-tree-node__content {
      height: 30px;
    }
    </style>
  • 相关阅读:
    jquery easy ui 学习 (8)basic treegrid
    jquery easy ui 学习 (7) TreeGrid Actions
    jquery easy ui 学习 (6) basic validatebox
    jquery easy ui 学习 (5) windowlayout
    jquery easy ui 学习 (4) window 打开之后 限制操纵后面元素属性
    提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll
    visual studio 添加虚线的快捷键
    VS2010打开项目时,出现“已经在解决方案中打开了具有该名称的项目”问题的解决方案
    visual studio 编译时 出现 Files 的值 乱码
    微信 连接被意外关闭
  • 原文地址:https://www.cnblogs.com/dianzan/p/13397389.html
Copyright © 2011-2022 走看看