vue3中使用ant-design-vue的layout组件实现动态导航栏功能(1~2级)

2023-11-06

目录

0 前言

1 准备工作

1.1 安装ant-design-vue

1.2 安装图标组件包

2 选择组件

3 路由文件

4 Vue导航页面

5 最终效果


0 前言

        最近在自己搞一个前后端小项目,前端想使用ant-design-vue的layout组件实现动态导航栏和面包屑,但是网上的资料较少,所以我就自己整合实现了一下,在此记录分享。

1 准备工作

        基于一个新建的Vue3项目上实现。

1.1 安装ant-design-vue

        官方文档:Components Overview - Ant Design Vue (antdv.com)

        安装:

npm i --save ant-design-vue

        全局注册:

import { createApp } from 'vue';
import Antd from 'ant-design-vue';
import App from './App';
import 'ant-design-vue/dist/antd.css';

const app = createApp(App);

app.use(Antd).mount('#app');

1.2 安装图标组件包

npm install --save @ant-design/icons-vue

        main.js中引用并全局注册

import * as Icons from '@ant-design/icons-vue'
//全局注册图标
const icons = Icons
for (const i in icons) {
  app.component(i, icons[i])
}

2 选择组件

        如下图所示,复制组件代码:

3 路由文件

        router/index.js文件

import { createRouter, createWebHashHistory } from 'vue-router'

const routes = [
  {
    //导航页
    path: '/layout',
    name: 'layout',
    meta: {
      title: '首页',
      keepalive: true
    },
    component: () => import('@/views/layout/'),
    children: [
      {
        //欢迎页
        path: '/layout',
        name: 'welcome',
        meta: {
          title: '首页',
          keepalive: true
        },
        component: () => import('@/views/welcome/')
      },
      {
        //实时数据
        path: '/runtimeData',
        name: 'runtimeData',
        meta: {
          title: '实时数据',
          keepalive: true
        },
        component: () => import('@/views/runtimeData/')
      },
      {
        //数据分析
        path: '/dataAnalysis',
        name: 'dataAnalysis',
        meta: {
          title: '数据分析',
          keepalive: true
        },
        component: () => import('@/views/dataAnalysis/')
      },
      {
        //数据处理(增删改查)
        path: '/dataManage',
        name: 'dataManage',
        meta: {
          title: '数据总览',
          keepalive: true
        },
        component: () => import('@/views/dataManage/')
      },
      {
        //查看用户信息
        path: '/showUserInfo',
        name: 'showUserInfo',
        meta: {
          title: '查看用户信息',
          keepalive: true
        },
        component: () => import('@/views/my/showUserInfo.vue')
      },
      {
        //修改用户信息
        path: '/editUserInfo',
        name: 'editUserInfo',
        meta: {
          title: '修改用户信息',
          keepalive: true
        },
        component: () => import('@/views/my/editUserInfo.vue')
      },
    ]
  },
  {
    //登录页面
    path: '/login',
    name: 'login',
    meta: {
      title: '登录',
      keepalive: true
    },
    component: () => import('@/views/login/index.vue')
  },

]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

4 Vue导航页面

        views/layout/index.vue,主要关注标签a-layout中的内容及相关变量

<template>
  <a-layout id="components-layout-demo-custom-trigger" style="min-height: 100vh">
    <a-layout-sider v-model:collapsed="collapsed" collapsible>

      <div class="logo">
        温湿度数据显示
      </div>


      <a-menu @click="navClick"
              v-model="currentSelectChild"
              @openChange="onOpenChange"
              :openKeys="currentParent"
              :inline-collapsed="collapsed"
              :selectedKeys="[route.path]"
              theme="dark"
              mode="inline"
      >

        <template v-for='(item,index) in NavDataInfo.NavData'>
          <a-sub-menu :key="item.Path" v-if='item.Child.length > 0'>
            <template #title>
              <a-icon>
                <meh-outlined/>
              </a-icon>
              <span>{{item.Title}}</span>
            </template>
            <a-menu-item v-for="(itChild,ind) in item.Child" :key="itChild.Path">
              <a-icon>
                <meh-outlined/>
              </a-icon>
              <router-link :to="itChild.Path">
                <!--根据路径去跳转页面-->
                {{itChild.Title}}
              </router-link>
            </a-menu-item>
          </a-sub-menu>


          <a-menu-item :key="item.Path" v-else>
            <a-icon>
              <meh-outlined/>
            </a-icon>
            <router-link :to="item.Path">
              <a-icon :type="item.Icons"/>
              <span>{{item.Title}}</span>
            </router-link>
          </a-menu-item>

        </template>

      </a-menu>

    </a-layout-sider>
    <a-layout>
      <a-layout-header style="background: #fff; padding: 0">
        <div id="header">
          <div id="left">
            <span>作者:</span>
          </div>
          <div id="right">
            <a-avatar src="https://joeschmoe.io/api/v1/random"/>
            <el-dropdown>
              <span class="el-dropdown-link">
                User
                <el-icon class="el-icon--right">
                  <arrow-down />
                </el-icon>
              </span>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item><router-link to="/showUserInfo">我的信息</router-link></el-dropdown-item>
                  <el-dropdown-item><router-link to="/editUserInfo">修改信息</router-link></el-dropdown-item>
                  <el-dropdown-item><span @click="outLogin">退出登录</span></el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
        </div>
      </a-layout-header>
      <!--      <keep-alive>-->
      <a-layout-content style="margin: 0 16px">
        <!-- 面包屑 -->
        <a-breadcrumb style="margin: 16px 0" separator=">">
          <!-- 自定义返回函数 ←-->
          <a-breadcrumb-item @click="goback">
            <a-icon>
              <import-outlined/>
            </a-icon>
            返回
          </a-breadcrumb-item>
          <a-breadcrumb-item v-for="(item, index) in breadList" :key="item.name">
            <router-link v-if="item.name !== name && index !== 1"
                         :to="{ path: item.path === '' ? '/' : item.path }">
              {{ item.meta.title }}
            </router-link>
            <span v-else>
              {{ item.meta.title }}
            </span>
          </a-breadcrumb-item>
        </a-breadcrumb>
        <!--          <transition>-->
        <div :style="{ padding: '24px', background: '#fff', minHeight: '100%' }">
          <router-view/>
        </div>
        <!--          </transition>-->
      </a-layout-content>
      <!--      </keep-alive>-->
      <a-layout-footer style="text-align: center">
        Great Project ©2022 Created by 
      </a-layout-footer>
    </a-layout>
  </a-layout>
</template>
<script setup>
  import { ref, reactive, onBeforeMount, watch, createVNode } from 'vue'
  import { useRouter, useRoute } from 'vue-router'
  import { Modal, message } from 'ant-design-vue'
  import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
  import myRouter from '@/router'
  import { ArrowDown } from '@element-plus/icons-vue'
  //************************************************data部分
  const route = useRoute()
  const router = useRouter()
  const collapsed = ref(false)
  const selectedKeys = ref(['0'])
  const name = ref('')
  const breadList = ref([])
  const NavDataInfo = reactive({
    NavData: [
      {
        NavID: '0',
        Icons: 'home',
        Title: '首页',
        Path: '/layout',
        Child: []
      },
      {
        NavID: '1',
        Icons: 'meh',
        Title: '实时数据',
        Path: '/runtimeData',
        Child: []
      },
      {
        NavID: '2',
        Icons: 'like',
        Title: '数据管理',
        Path: '/dataManage',
        Child: [
          {
            NavID: '2-1',
            Icons: 'man',
            Title: '数据总览',
            Path: '/dataManage',
            Child: []
          },
        ]
      },
      {
        NavID: '3',
        Icons: 'key',
        Title: '数据分析',
        Path: '/dataAnalysis',
        Child: []
      },
    ],
  })
  //************************************************data部分

  //************************************************方法
  const getBreadcrumb = () => {
    breadList.value = []
    name.value = route.name
    route.matched.forEach(item => {
      breadList.value.push(item)
    })
    console.log(breadList.value)
    console.log(name.value)
    console.log(route)

  }
  // 返回上一页,调用的组件 router.back();
  const goback = () => {
    //点击了返回按钮
    router.back()
  }

  //退出登录
  const outLogin = () => {
    Modal.confirm({
      title: '您确定要退出登录吗?',
      icon: createVNode(ExclamationCircleOutlined),
      content: createVNode('div', {
        style: 'color:red;',
      }, '点击OK则将退出!'),
      onOk () {
        // console.log('OK', key)
        message.success('退出登录!')
        myRouter.push({ path: "/login" });
      },
      onCancel () {
        // console.log('Cancel')
        message.success('取消成功!')
      },
      class: 'test',
    })
  }

  //监视路由
  watch(() => route.path, getBreadcrumb)

  //*************************************************方法

  //*************************************************生命周期
  onBeforeMount(() => {
    getBreadcrumb()
  })
  //*************************************************生命周期


</script>
<style scoped>
  #components-layout-demo-custom-trigger {
    height: 100%;
  }

  #components-layout-demo-custom-trigger .trigger {
    font-size: 18px;
    line-height: 64px;
    padding: 0 24px;
    cursor: pointer;
    transition: color 0.3s;
  }

  #components-layout-demo-custom-trigger .trigger:hover {
    color: #1890ff;
  }

  #components-layout-demo-custom-trigger .logo {
    height: 32px;
    background: rgb(127, 252, 255);
    margin: 16px;
    font-size: 20px;
    text-align: center;
    font-family: 宋体;
  }

  #header {
    display: flex;
    height: 70px;
    /*margin: 0;*/
    padding: 0;
  }

  #left {
    width: 80%;
    /*height: 25px;*/
    /*background-color: darksalmon;*/
    justify-content: flex-start;
    display: flex;
    align-items: center;
    margin-left: 16px;
  }

  #right {
    flex: 1;
    width: 20%;
    /*background-color: coral;*/
    /*height: 50px;*/
    justify-content: flex-end;
    display: flex;
    align-items: center;
    margin-right: 16px;
  }
  .example-showcase .el-dropdown-link {
    cursor: pointer;
    color: var(--el-color-primary);
    display: flex;
    align-items: center;
  }

</style>

        上面的代码中将路由文件中的路由表重新写了一个变量,主要是为了方便,并不是所有页面路由都要制作导航栏,这样就不用在router/index.js中添加路由时考虑太多。

5 最终效果

         效果如上图所示,我这里也写了一个面包屑,不过还有些问题,就交给大伙儿实现吧!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3中使用ant-design-vue的layout组件实现动态导航栏功能(1~2级) 的相关文章

  • 使用普通的旧 JS 动态渲染 DOM 元素的好方法是什么?

    我面临的挑战是使用普通的旧 Javascript 构建一个单页应用程序 不允许使用任何库或框架 虽然在 React 和 Angular 中创建动态 DOM 元素相当简单 但我提出的普通 JS 解决方案似乎很笨重 我想知道是否有一种特别更简洁
  • JavaScript(或 jQuery)中有“有焦点”吗?

    我可以这样做吗 也许通过插件 if form contact input hasFocus form contact input first focus 基本上 将焦点设置为第一个输入 但前提是用户尚未单击任何内容 我知道这也行 但是还有更
  • 尝试制作Linux终端但失败

    这可能是一个愚蠢的问题 可能很容易找到 但我对这一切都很陌生 我似乎找不到我要找的东西 或者至少我不知道我需要寻找什么 所以我在这里 所以我想做的是创建一种 Linux 终端 这就是我到目前为止所得到的 我所坚持的是实际输入文本部分 我一直
  • { ...obj1, obj2 } 到底做什么[重复]

    这个问题在这里已经有答案了 假设我们有两个对象 const state fishes some obj data animals some obj data const animals some NEW data 在Vuex中有一个方法re
  • 如何在 HTML 链接中使用 JavaScript 变量

    我正在开发的网站有一个标签指向与网站所具有的 URL 不同的 URL 我想做的是绕过使用下面的 trueURL 标记来查找网页的网址 因为我需要它来构造一些内部锚点 因为我需要网站的实际网址 以便内部锚点正常工作 我遇到的问题是我不知道应该
  • 按属性首字母对对象数组进行分组

    我对此有点挣扎 自从我编码 JavaScript 以来已经有一段时间了 试图转换它 items data name john name james name joe name brian name bojan name billy name
  • 如何使用 jQuery 在悬停元素旁边显示一个 div?

    假设我有severaldiv 像这样 EDIT div class ProfilePic a href img src lib css img profile pic1 png alt class ProfilePicImg a div c
  • jQuery:当使用 on .scroll 事件和警报时,firefox 似乎无限循环

    我的主模板之一中有以下 jQuery 代码 document scroll function var scroll top document scrollTop alert scroll top if scroll top lt 70 fi
  • 使用jquery,下拉列表选择更改时如何重定向?

    我有一个下拉列表 如果有人选择一个选项 我想根据选择重定向到另一个页面 我怎样才能通过 jquery 做到这一点 将逻辑绑定到 change 事件 并从中获取当前值 val 以确定用户应该被重定向到哪里 此示例假设位置直接存储在值本身中 m
  • IE9:奇怪的 JavaScript 错误

    我尝试在网站中显示 Google DFP 广告横幅时遇到错误 这些广告在除 IE9 之外的所有浏览器中展示 您可以在此处查看带有横幅的简单测试页面 离线演示 错误是 抛出异常但未捕获 google ads js 第 34 行字符 474 I
  • 如何从 HTML 图表中删除网址 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在 HTML 中创建一个图表 我正在使用 API amCharts 但问题是它在图表中显示文本 amchart 我怎样才能删除该文本
  • 从 Web 浏览器控件读取 Javascript 变量

    我正在尝试读取从表单上的 WebBrowser 控件加载和调用的 Javascript 变量的值 Example index html 引用名为 test js 的 javascript 在 test js 上 创建并填充了几个变量 然后i
  • 如何将 props 传递给模态

    我有一个购物应用程序 我可以在其中映射一些产品并将它们呈现在屏幕上 用户可以增加 减少数量 当数量达到 1 并且用户点击减少时 一些中间件会介入并询问他们是否确定要将其从购物篮中删除 如果他们单击 否 则会关闭模式并将其留在购物篮中 如果他
  • 是否有跨浏览器的 jQuery contentEditable 库? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 jQuery 插件 库 它可以使 contentEditable 属性在所有主要浏览器中正常工作 我什至可以不用 IE6
  • 函数声明可以出现在 JavaScript 的语句内部吗?

    请考虑将官方 ECMAScript 规范作为您答案的来源 而不是特定浏览器供应商发布的文档 我知道 Mozilla 用 函数语句 扩展了它的 JavaScript 实现 因此 根据 ECMAScript 规范 因此 其中定义的语法产生式 这
  • 时间序列折线图与轴不同步

    本实验基于这个d3官方例子 http bost ocks org mike path 我想要实现的是可视化时间序列数据的最后 x 分钟 我有这个代码的副本jsfiddle http jsfiddle net 225dC 3 单击以添加新数据
  • 如何在 AngularJS 中设置选择选项中的文本格式?

    我有以下 json 对象 scope values id 2 code Code 1 name Sample 1 id 4 code Code 2 name Sample 2 id 7 code Code 3 name Sample 3 在
  • 以编程方式访问使用数据 URI 作为源的 iframe

    我正在使用 数据 URI 以编程方式创建一个 iframe 该框架加载良好 但似乎以编程方式使用 iframe 会遇到跨域安全检查 var iframeDoc document getElementById myFrame contentW
  • 如何使我的响应式网站在手机上支持“请求桌面网站”?

    我有一个响应灵敏的动态网站 Java Servlet 驱动且完全手工编码 由于它是一个返回数据表的科学站点 因此某些选项在较小的视口宽度下不可用 然而 可能有些用户更喜欢在桌面网站上挣扎才能访问这些选项 我希望适应他们 我的问题是 对于 i
  • 返回语句后的声明

    function f return f1 function f1 return 5 f returns 5 为什么这有效 之后声明局部函数有什么好处return 这是好的做法吗 它之所以有效 是因为函数声明都是由解释器在第一次传递时评估的

随机推荐

  • 树的遍历-深度优先遍历和广度优先遍历

    深度优先遍历类似于树的先序遍历 假设给定初态是图中所有顶点均未被访问过 从图中某一顶点vi出发遍历图中的定义如下 首先访问出发点vi 并将其访问标志置为1 然后 从vi出发点依次搜索vi的每个邻接点vj 如vj未被访问过 则以vj为新的出发
  • 函数模板和类模板的实例化和具体化

    一 函数模板 1 显示实例化 explicit instantiation 和显示具体化 explicit specialization 的区别 1 形式上 显示实例化 template void Swap
  • estimate函数是什么?

    estimate 函数是用来估计参数值的函数 它通常用于统计学和机器学习中 用来求出一组样本数据的模型参数的最优解
  • VS2008/VS2010安装时提示VC++9.0 Runtime安装失败问题的解决方法

    查了一下 有以下几种解决方法 1 http blog csdn net zlqqhs article details 8821608 2 https dotblogs com tw johnny archive 2010 07 16 165
  • 矩阵向量求导(Matrix calculus)

    原文地址 注 不要把它和几何运算或者是向量运算混淆 前言 在数学中 矩阵微积分是进行多变量微积分的一种特殊符号 特别是在矩阵的空间上 它将关于许多变量的单个函数的各种偏导数和 或关于单个变量的多变量函数的偏导数收集到可以被视为单个实体的向量
  • linux从EMMC启动或TFTP启动的UBOOT参数

    从EMMC启动内核及设备树 setenv bootargs console ttymxc0 115200 root dev mmcblk1p2 rootwait rw setenv bootcmd mmc dev 1 fatload mmc
  • java-logback记录日志到指定文件并且压缩保存日志

    yml配置文件中加入如下配置 logging config classpath logback spring xml 项目根目录下的xml配置文件 level root info 全局日志的级别 file name mes log 输出日志
  • nvm 在 Windows 上的使用

    NVM Node Version Manager 是一个用于管理和切换多个 Node js 版本的工具 它允许你在同一台机器上同时安装和使用不同版本的 Node js 而无需手动安装和卸载 之前都是只安装一个版本的 node js 该更新时
  • 2021年字节跳动、阿里等大厂最全Android面试题,已开源

    前言 对于字节跳动的二面三面而言 Framework MVP架构 HashMap原理 性能优化 Flutter 源码分析等问题都成高频问点 然而很多的朋友在面试时却答不上或者答不全 今天在这分享下这些问点的视频解析给大家 希望对有需要的朋友
  • 一文教会你如何用 Python 分割合并大文件

    有时候 我们需要把一个大文件发送给别人 但是限于传输通道的限制 比如邮箱附件大小的限制 或者网络状况不太好 需要将大文件分割成小文件 分多次发送 接收端再对这些小文件进行合并 今天就来分享一下用 Python 分割合并大文件的方法 思路及实
  • 2017版VisualStudio asp.net利用ZXing生成条形码、二维码

    2017版VisualStudio asp net利用ZXing生成条形码 二维码 一 在asp net项目中添加ZXing 1 右击项目 管理NuGet程序包 2 搜索ZXing 下载ZXing net并安装即可 二 生成条形码 1 页面
  • Arch Linux 安装(痛苦版)

    我已经用了两年的Linux FreeBSD 平时都是硬盘安装 除了BSD有点阻碍 linux不在话下 但是Arch Linux让我感到无助 虽然最后是用光驱安装成功 为什么要装archLinux 我的二手笔记本 CPU P3 700 RAM
  • Test Driven Development感悟

    编程的思想有面向过程编程 面向对象编程 面向接口编程 面向接口编程是现在很多公司在使用的 面向接口效率更好 而且使得业务代码更加简洁易调试 面向对象的方法使得代码会多出很多接口 可以为以后的使用留接口 但是开发效率不高 面向过程写代码 可以
  • 8-高精度计算(加法)

    我们知道 在C语言和C 中对于所能存储的数值的最大值是有明确的上限的 但是我们有时候会需要去计算一些数值比较大的数字 例如位数为1000 10000的数字的加减运算 这时候我们就需要使用新的运算方法了 这里引入高精度的大数据计算 它可以用计
  • SDIO接口(3)——SDIO总线接口

    SDIO总线接口 SDIO是在SD标准上定义了一种外设接口 故名思义 就是SD的I O接口的意思 SD本来是记忆卡的标准 但是现在把SD连接一些外围I O使用 这样边形成了SDIO接口 SDIO本身只是一种接口技术 类似于SPI接口 通过I
  • Java itext为pdf 文件添加水印核心功能代码片段

    param content param pageRect param waterMarkContent 水印文字 private static void addWaterMark PdfContentByte content Rectang
  • 如何利用Nginx实现动态负载均衡

    为什么用Nginx Nginx是经过实践证明的 安全稳定的反向代理服务器 淘宝 新浪等大型互联网公司都有Nginx的身影 Nginx经过线上各种网络环境验证 能够帮你隔离各种复杂的网络环境 轻松支持10000 的同时在线连接数 同时拥有多种
  • vs2019创建c语言_VS2019初步使用

    前言 前段时间把电脑重置了下 导致很多软件都被删除了 所以重新安装了 顺便把一些 陈年落后 的软件更新到了最新版 新版的软件和之前相比的确区别很大 更人性化了 功能也增加了不少 体会最深的就是Adobe Photoshop 2020 对新手
  • WordPress初学者入门教程-页面与文章

    本文源自 https wpeyes com wordpress 当你想要添加书面内容到你的网站 你有两个选择 你可以创建一个页面或一篇文章 在添加 编辑方面 这两者非常相似 但在功能上其实是相当不同的 对于刚接触WordPress的人 或者
  • vue3中使用ant-design-vue的layout组件实现动态导航栏功能(1~2级)

    目录 0 前言 1 准备工作 1 1 安装ant design vue 1 2 安装图标组件包 2 选择组件 3 路由文件 4 Vue导航页面 5 最终效果 0 前言 最近在自己搞一个前后端小项目 前端想使用ant design vue的l