vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue3使用ant-design-vue实现动态导航栏

vue3中使用ant-design-vue的layout组件实现动态导航栏和面包屑功能

作者:光年在眼前

这篇文章主要介绍了vue3中使用ant-design-vue的layout组件实现动态导航栏和面包屑功能,基于一个新建的Vue3项目上实现,本文结合示例代码给大家介绍的非常详细,需要的朋友可以参考下

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 最终效果

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

到此这篇关于vue3中使用ant-design-vue的layout组件实现动态导航栏和面包屑功能的文章就介绍到这了,更多相关vue3使用ant-design-vue实现动态导航栏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文