el-tree常用操作

一、定义

html 复制代码
<el-tree
            class="myTreeClass"
            :data="dirTreeData"
            :props="dirTreeProps"
            :filter-node-method="filterDirTree"
            :expand-on-click-node="false"
            node-key="id"
            @node-click="dirTreeNodeClick"
            :allow-drop="dirTreeAllowDrop"
            @node-drop="dirTreeNodeDrop"
            ref="dirTreeRef"
            style="margin-top: 10px"
            draggable>
</el-tree>
  • data:dirTreeData 数组

  • props:dirTreeProps 可指定树的label/children等数据

    javascript 复制代码
    const dirTreeProps = ref({
      children:'children',
      label: function (node){
        return node.dirItem.name
      }
    })

二、插槽

插槽中可以定义icon、目录名称样式等数据

html 复制代码
  <template #default="{ node,data }">
		<div style="display: flex;flex-grow:1">
            <div style="display: flex">
              <el-icon style="margin-right: 3px">
                <FolderOpened v-if="node.expanded" />
                <Folder v-else />
              </el-icon>
              <div>
                <div v-if="data.isEdit" style="margin-left: 8px">
                  <el-input class="dirNameInput" v-model="data.dirItem.name" size="small" @blur="updateDirName(node)"></el-input>
                </div>
                <div v-else style="margin-left: 8px">{{node.label}}</div>
              </div>
            </div>
            <div style="display:flex;margin-left: auto">
              <div>{{data.dirItem.countNow}}</div>
              <div style="margin-left: 2px">({{data.dirItem.countAll}})</div>
            </div>
			</div>
          </template>

三、拖拽目录限制判断

通过el-tree绑定:allow-drop="dirTreeAllowDrop",实现对拖拽目标不能是根节点的限制

javascript 复制代码
const dirTreeAllowDrop = (moveNode,inNode)=>{
  // 拖拽的目标节点不能是根节点
  return inNode.data.id !== rootNodeId.value;
}

四、拖拽目录完成后事件处理

通过el-tree绑定@node-drop="dirTreeNodeDrop",实现对拖拽目标不能是根节点的限制

javascript 复制代码
const dirTreeNodeDrop = (moveNode,inNode,type)=>{
  if (type === 'inner'){
    emitClickTreeNode(inNode)
  }else {
    emitClickTreeNode(moveNode)
  }
}

五、设置某个节点选中状态

javascript 复制代码
dirTreeRef.value.setCurrentKey(targetNode.key)

六、调用某个节点点击事件

javascript 复制代码
dirTreeRef.value.$emit('node-click',targetNode.data,targetNode,null)

七、根据nodeId获取当前节点data数据

javascript 复制代码
const findTreeDataById = (nodeId)=>{
  const traverse = (nodes)=>{
    for(const node of nodes){
      if (node.id === nodeId) return node;
      if (node.children && node.children.length > 0){
        const found = traverse(node.children)
        if (found) return found
      }
    }
  }
  return traverse(dirTreeData.value)
}

八、根据nodeId获取父节点data数据

javascript 复制代码
const findParentTreeDataById = (nodeId)=>{
  const traverse = (nodes)=>{
    for(const node of nodes){
      if (node.children && node.children.length > 0){
        if (node.children.some(child=>child.id === nodeId)){
          return node;
        }
        const parentNode = traverse(node.children)
        if (parentNode) return parentNode
      }
    }
  }
  return traverse(dirTreeData.value)
}

九、根据nodeId获取Tree组件中当前节点node

javascript 复制代码
const parentNode = dirTreeRef.value.getNode(parentData.id)

十、新增目录

javascript 复制代码
const addDir = async ()=>{
  if (!currentSelectedNode.value){
    ElMessage.error('未找当前节点,请刷新后重试')
    return
  }
  // 后台请求新增目录
  let newDir = {
    xxxx
  }
  const dirAddResp = await dirService.dirAdd(newDir)
  const {data:{data:dirAddId}} = dirAddResp
  if(!dirAddId){
    ElMessage.error('保存失败,未获取到新增目录id')
    return
  }
  // 增加对应树节点
  let newDirData = {
    id:dirAddId,
    dirItem:{
      id:dirAddId,
      name:'新建目录',
      countNew:0,
      countAll:0
    },
    isEdit:true,
    children:[]
  }
  currentSelectedNode.value.children.push(newDirData)
  await nextTick(()=>{
    // 展开其父节点
    const parentData = findParentTreeDataById(newDirData.id)
    const parentNode = dirTreeRef.value.getNode(parentData.id)
    parentNode.expand()
    // 定位到当前节点
    const newDirNode = dirTreeRef.value.getNode(newDirData.id)
    emitClickTreeNode(newDirNode)
    // 输入框焦点定位
    nextTick(()=>{
      setTimeout(()=>{
        const input = document.querySelector('.dirNameInput .el-input__inner')
        if (input){
          input.focus()
        }
      },500)
    })
  })
}

十一、删除目录

javascript 复制代码
const deleteDir = async ()=>{
  // 后台请求删除节点
  const dirDeleteResp = await dirService.caseDirDelete(currentSelectedNode.value.id)
  const {data:{errno:respErrno}} = dirDeleteResp
  if (respErrno !== 0) {
    ElMessage.error('节点删除失败,请刷新后重试')
    return
  }
  // 从父节点中移除当前节点
  const parentData = findParentTreeDataById(currentSelectedNode.value.id)
  const index = parentData.children.indexOf(currentSelectedNode.value)
  parentData.children.splice(index,1)
  // 将焦点定位至父节点
  const parentNode = dirTreeRef.value.getNode(parentData.id)
  await nextTick(()=>{
    emitClickTreeNode(parentNode)
  })
}

十二、目录重命名

先把目录的输入框显示出来,并将焦点置于输入框

javascript 复制代码
const editDirName = async ()=>{
  const treeData = findTreeDataById(currentSelectedNode.value.id)
  treeData.isEdit = true
  await nextTick(()=>{
    const input = document.querySelector('.dirNameInput .el-input__inner')
    if (input){
      input.focus()
    }
  })
}

然后再input @blur=updateDirName时,调用后台保存

javascript 复制代码
const updateDirName = async(node)=>{
  // 后台请求重命名目录
  const dirRenameResp = await dirService.dirRename(node.data.id,node.data.dirItem.name)
  const {data:{errno:respErrno}} = dirRenameResp
  if (respErrno !== 0) {
    ElMessage.error('节点重命名失败,请刷新后重试')
    return
  }
  node.data.isEdit = false
}
相关推荐
银迢迢1 小时前
如何创建一个Vue项目
前端·javascript·vue.js
deming_su4 小时前
第六课:数据库集成:MongoDB与Mongoose技术应用
javascript·数据库·mongodb·node.js·html
几何心凉4 小时前
如何解决Vue组件间传递数据的问题?
前端·javascript·vue.js
七灵微4 小时前
【前端】BOM & DOM
前端·javascript·servlet
yqcoder4 小时前
ES6 解构详解
前端·javascript·es6
青阳流月4 小时前
js读书笔记(补充知识)
前端·javascript
Moment6 小时前
从方案到原理,带你从零到一实现一个 前端白屏 检测的 SDK ☺️☺️☺️
前端·javascript·面试
鱼樱前端6 小时前
Vue3 + TypeScript 整合 MeScroll.js 组件
前端·vue.js
拉不动的猪7 小时前
刷刷题29
前端·vue.js·面试
武昌库里写JAVA7 小时前
原生iOS集成react-native (react-native 0.65+)
vue.js·spring boot·毕业设计·layui·课程设计