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
}
相关推荐
web行路人4 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱0015 分钟前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼92123 分钟前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂26 分钟前
ajax关于axios库的运用小案例
前端·javascript·ajax
嚣张农民1 小时前
推荐3个实用的760°全景框架
前端·vue.js·程序员
周亚鑫1 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
落魄小二1 小时前
el-table 表格索引不展示问题
javascript·vue.js·elementui
y5236481 小时前
Javascript监控元素样式变化
开发语言·javascript·ecmascript
fruge2 小时前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
neter.asia2 小时前
vue中如何关闭eslint检测?
前端·javascript·vue.js