element-plus树形控件实现页面跳转

424 阅读3分钟

需求源源不断,代码越写越乱 小菜鸡成长日记

今天终于把分到的任务做完了,接下来就开始回顾这几天遇到的问题了~

前几天遇到一个需求,通过页面左侧树形控件实现右侧的子页面跳转。

先从简单的来...

给每个节点设置id,给页面绑定一个id,将树形节点的id赋值给页面绑定的id,然后通过判断页面id来实现切换的功能。

<template>
  <div class='main'>
    <div class='left'>
      <el-tree ref='treeRef' :data="data" :props="defaultProps" @node-click="handleNodeClick" highlight-current />
    </div>
    <div class='right'>
        <div name='页面1' :id='node' v-if='node == 2' style='backgroundColor: pink'>1-1</div>
        <div name='页面2' :id='node' v-if='node == 4'  style='backgroundColor: green'>2-1</div>
        <div name='页面3' :id='node' v-if='node == 6'  style='backgroundColor: yellow'>3-1</div>
    </div>
  </div>
 
</template>

<script lang="ts" setup>
  import {ref,watch} from 'vue'
interface Tree {
  id:number
  label: string
  children?: Tree[]
}

//树形数据
const data: Tree[] = [
  {
    id:1,
    label: 'Level one 1',
    children: [
      {
        id:2,
        label: 'Level two 1-1',
        
      },
    ],
  },
  {
    id:3,
    label: 'Level one 2',
    children: [
      {
        id:4,
        label: 'Level two 2-1',
      },
    ],
  },
  {
    id:5,
    label: 'Level one 3',
    children: [
      {
        id:6,
        label: 'Level two 3-1',
      },
    ],
  },
]
  
const defaultProps = {
  children: 'children',
  label: 'label',
}

// 给每个报表页面设置id
const node = ref()
const handleNodeClick = (data: Tree) => {
//获取树形节点id
  let id = data.id
  //将树形节点id赋值给报表页面id
  node.value = id
  // console.log('111', node.value)
}
</script>
<style scpoe>
  .main{
    display: flex
  }
  .left {
    padding-right: 30px
  }
  .right {
    flex:1
  }
</style>

效果图:

image.png

需求升级...

要求树形节点的文字是通过动态路由的形式获取的,并且每个节点下的页面节点需要展示在面包屑导航上。

针对于我做的项目来说:首先需要获取到routes,然后获取它的name,title等等,将title的值取出来,作为要渲染的数据。就是将获取的这些数据作为树形控件需要绑定的数据。然后最关键的一步就是将所选的子层展现在面包屑上。

路由部分:

export default [
  {
    path: '/reportCenter',
    name: 'reportCenter',
    meta: {
      title: '报表中心',
      icon: 'report'
    },
    component: () => import('@/layouts/admin.vue'),
    children: [
      {
        path: '',
        component: () => import('@/views/reportCenter/reportList/index.vue'),
        meta: {
          hideMenu: true
        }
      },
      {
        path: 'spotReport',
        name: 'spotReport',
        meta: {
          title: '报表',
          hideMenu: true
        },
        redirect: 'reportCenter',
        children: [
          {
            path: 'spotDetail',
            name: 'spotDetail',
            meta: {
              title: '明细',
              hideMenu: true
            }
          },
          {
            path: 'spotTask',
            name: 'spotTask',
            meta: {
              title: '完成情况',
              hideMenu: true
            }
          }
        ]
      },

动态获取树形节点的文字

const initTree = () => {
//获取当前路由信息的存储对象
  const route = useRouteStore()
  //从route对象中获取名为accessRoutes的属性,该属性是一个数组,包含了当前用户有权限访问的所有路由信息。然后使用Array.prototype.find()方法,查找路径为/reportCenter的路由信息,并将其赋值给名为reportRoute的常量。
  const reportRoute = route.accessRoutes.find(item => item.path === '/reportCenter')
  //如果reportRoute存在,且有children属性,则将其子路由信息的第二个开始的部分(即去掉第一个空的路由)截取出来,赋值给名为tree的常量,否则将tree赋值为空数组。如果reportRoute不存在,则将tree也赋值为空数组。
  const tree = reportRoute ? (reportRoute.children ? reportRoute.children.slice(1) : []) : []
  //将格式化后的树形结构的JSON数据,赋值给名为originTree的响应式变量的`value`属性。
  originTree.value = formatterTree(tree)
}



// 这个返回的结果就是树的JSON数据
const formatterTree = (tree: any[]) => {
//定义名为res的空数组,用于存储格式化后的树形结构的数据。
  const res: any[] = []
// 遍历的是路由,路由的name作为唯一标识node-key,然后获取路由的title,若children存在就使用递归遍历出来
  tree.forEach(item => {
    res.push({
      treeKey: item.name,
      label: item.meta.title,
      children: item.children ? formatterTree(item.children) : []
    })
  })
  return res
}

面包屑部分:

//这个函数主要是根据当前路由信息和当前选中的节点来修改面包屑导航和按钮权限信息
const changeConfig = () => {
  //获取一个路由存储对象
  const route = useRouteStore()
  const reportRoute = route.accessRoutes.find(item => item.path === '/reportCenter')
  
 //如果reportRoute存在,则先判断reportRoute是否为null或undefined,如果不是,则使用可选链操作符访问reportRoute.children属性,并使用Array.prototype.forEach()方法遍历reportRoute.children数组中的每个子路由信息。
  reportRoute && reportRoute.children?.forEach(child => {
      child.children?.forEach(item => {
        if (item.name === currentNodeKey.value && reportRoute.meta) {
        
        //清空reportRoute.meta.breadcrumbNeste数组中的所有元素
          reportRoute.meta.breadcrumbNeste?.splice(0)
          
        //遍历数组中的所有元素并push进reportRoute.meta.breadcrumbNeste
          item.meta?.breadcrumbNeste?.forEach(node => {
            reportRoute.meta && reportRoute.meta.breadcrumbNeste?.push(node)
          })
          reportRoute.meta.btnPermission?.splice(0)
          item.meta?.btnPermission?.forEach(node => {
            reportRoute.meta && reportRoute.meta.btnPermission?.push(node)
          })
        }
      })
    })
}