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 小时前
一文解释清楚OpenHarmony面向全场景的分布式操作系统
vue.js
暴富的Tdy1 小时前
【CryptoJS库AES加密】
前端·javascript·vue.js
neeef_se1 小时前
Vue中使用a标签下载静态资源文件(比如excel、pdf等),纯前端操作
前端·vue.js·excel
℘团子এ1 小时前
js和html中,将Excel文件渲染在页面上
javascript·html·excel
z千鑫2 小时前
【前端】入门指南:Vue中使用Node.js进行数据库CRUD操作的详细步骤
前端·vue.js·node.js
生产队队长3 小时前
项目练习:element-ui的valid表单验证功能用法
前端·vue.js·ui
胡西风_foxww3 小时前
【es6复习笔记】Promise对象详解(12)
javascript·笔记·es6·promise·异步·回调·地狱
web137656076434 小时前
WebStorm 创建一个Vue项目
ide·vue.js·webstorm
秃头女孩y4 小时前
【React中最优雅的异步请求】
javascript·vue.js·react.js