vue3 + elementplus 左侧菜单 无限无线递归渲染

简介: vue3 + elementplus 左侧菜单 无限无线递归渲染

在做一些管理后台的时候;一般会有权限不同看到的菜单也不同。而且菜单结构也是不确定有多少级别,或者无限级别。这里就需要组件递归渲染了

效果图:

后端菜单接口返回如下面这样的:

 mm: [
               {
                   path:'hh',
                   name:'系统管理',
                   func_fid: 0,
                   id: 1,
                   children: [
                       {
                           id: 1,
                           func_fid: 1,
                           path:'son1',
                           name: '系统管理儿子',
                       },
                       {
                           id: 2,
                           func_fid: 1,
                           path:'hhh',
                           name: '系统管理-角色',
                           children: [
                               {
                                   id: 2,
                                   func_fid: 1,
                                   path: 'son1-1-1',
                                   name: '角色管理',
                                   children:[
                                       {
                                           id: 2,
                                           func_fid: 2,
                                           path: 'son1-1-1',
                                           name: '角色管理儿子',
                                           children:[
                                               {
                                                   id: 2,
                                                   func_fid: 2,
                                                   path: 'son1-1-1',
                                                   name: '角色管理儿子-----孙子',
                                               }
                                           ]
                                       }
                                   ]
                               }
                           ]
                       },
                       {
                           id: 12,
                           path: 'son1-2',
                           name: '用户管理'
                       }
                   ]
               },
               {
                   path:'ss',
                   name:'教学管理',
                   id: 2,
                   func_fid: 0,
                   children: [
                       {
                           path:'son2',
                           name:'教学管理儿子',
                           id: 2,
                           func_fid: 2,
                       }
                   ]
               },
               {
                   path:'zz',
                   name:'行政管理',
                   id: 3,
                   func_fid: 0,
                   children: [
                       {
                           path:'son3',
                           name:'行政管理儿子',
                           id: 3,
                           func_fid: 3,
                       }
                   ]
               },
           ]

左侧菜单部分代码home.vue

<template>
 <el-container>
    <el-aside width="collapse ? 200px : 70px">
      <el-button color="#626aef" @click="collapseToggle()">
        <el-icon>
          <Expand v-if="collapse" />
          <Fold v-else />
        </el-icon>
      </el-button>
      <el-menu
          :collapse="collapse"
          default-active="2"
          class="el-menu-vertical-demo"
          @open="handleOpen"
          @close="handleClose"
          active-text-color="#ffd04b"
          text-color="#fff"
          background-color="transparent"
          router
          @select="gg"
         >
       <left :dataToSon="store.mm" />
      </el-menu>
    </el-aside>
    <el-container>
      <el-header height="80px">
        <h1>大可的管理系统 - v1.0</h1>
        <div>
          <img src="@/assets/111.jpg" alt="">
          <span></span>
          <el-button type="primary" @click="LogOut">退出登录</el-button>
        </div>
      </el-header>
      <el-main>
        <tab></tab>
      </el-main>
      <el-footer height="50px">
        <p>&copy; 版权所有: 大可</p>
      </el-footer>
    </el-container>
  </el-container>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useRouter } from "vue-router";
import left from "./left.vue";
import  tab from './tab.vue';
import { ElMessage, ElMessageBox} from "element-plus";
import { useAuthStore } from '@/store'
const store = useAuthStore();
const collapse = ref<boolean>(false)
const router = useRouter();
const collapseToggle = () => {
  collapse.value = !collapse.value
}
const ggvv  = ref([1,2,3])
const handleOpen = () => {
  console.log('展开')
}
const gg = (e) => {
  console.log(e)
}
const handleClose = () => {
  console.log('收起')
}
const LogOut = () => {
  ElMessageBox.confirm(
      '确定要退出登录?',
      'Warning',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
  )
      .then(() => {
        router.replace('/login')
        ElMessage({
          type: 'success',
          message: '退出成功',
        })
      })
      .catch(() => {
        ElMessage({
          type: 'info',
          message: '您取消了退出',
        })
      })
}
</script>
<style scoped>
.el-header {
  background: url("@/assets/111.jpg");
  background-color: #f3d19e;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.el-header h1 {
  font-size: 26px;
  color: #fff;
  letter-spacing: 10px;
}
.el-header div {
  margin-right: 30px;
}
.el-header img {
  width: 40px;
  border-radius: 40px;
  vertical-align: middle;
  margin-right: 10px;
}
.el-header span {
  font-size: 18px;
  color: #fff;
  margin-right: 10px;
}
.el-header el-button {
  margin-left: 10px;
}
.el-aside {
  height: 100vh;
  background: url('@/assets/111.jpg');
  transition: width 0.3s;
  text-align: right;
}
.el-aside .el-button {
   margin: 20px 10px 20px 0;
 }
.el-aside .el-menu {
  border-right: none;
}
.el-footer {
  background-color: #EBEEF5;
  display: flex;
  align-items: center;
}
.el-footer p {
  font-size: 12px;
  color: #666;
}
</style>

菜单left: 组件

<script setup lang="ts">
import { ref, defineProps } from 'vue';
import { useAuthStore } from '@/store';
type HeaderProps = {
  dataToSon: number[];
};
// 2. type 声明的HeaderProps 用 defineProps注册
const zz = defineProps<HeaderProps>();
const hhkk = zz.dataToSon;
console.log('-------------------')
console.log(hhkk)
console.log('-------------------')
const list = ref<Array<object>>([]);
const store = useAuthStore();
const gg = () => {
  console.log('ss')
}
</script>
<template>
    <template v-for="(item, index) in hhkk" :key="item.id">
      <!-- 非叶子节点 -->
      <el-sub-menu v-if="item.children" :index="item.id">
        <template #title>
          <el-icon>
            <Setting />
          </el-icon>
          <span v-text="item.name"></span>
        </template>
        <left :dataToSon="item.children"/>
      </el-sub-menu>
      <!-- 叶子节点(功能节点) -->
      <el-menu-item v-else :index="item.path">
        <el-icon>
          <Menu />
        </el-icon>
        <span v-text="item.name"></span>
      </el-menu-item>
    </template>
</template>
<style scoped lang="stylus">
</style>

至此左侧菜单就可以了


目录
相关文章
|
23天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
126 64
|
23天前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
103 60
|
23天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
29 8
|
23天前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
23 1
|
23天前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
33 1
|
23天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
1月前
|
JavaScript 索引
Vue 3.x 版本中双向数据绑定的底层实现有哪些变化
从Vue 2.x的`Object.defineProperty`到Vue 3.x的`Proxy`,实现了更高效的数据劫持与响应式处理。`Proxy`不仅能够代理整个对象,动态响应属性的增删,还优化了嵌套对象的处理和依赖追踪,减少了不必要的视图更新,提升了性能。同时,Vue 3.x对数组的响应式处理也更加灵活,简化了开发流程。
|
1月前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
61 1
|
27天前
|
JavaScript 前端开发 API
从Vue 2到Vue 3的演进
从Vue 2到Vue 3的演进
39 0
|
27天前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
54 0
下一篇
DataWorks