【完整项目搭建】基于vue-cli实现vue前端搭建考试系统——④项目开发基于vue-router【嵌套路由】实现导航栏切换效果

一、配置嵌套路由【功能实现】

1、打开vue-router官方文档,查找嵌套路由部分

针对页面不变的部分,定义为外层路由,对于改变的部分,在children中定义为子路由

官方示例代码如下:

const router = new VueRouter({
  routes: [
    {
      path: '/user/:id',
      component: User,
      children: [
        {
          // 当 /user/:id/profile 匹配成功,
          // UserProfile 会被渲染在 User 的 <router-view> 中
          path: 'profile',
          component: UserProfile
        },
        {
          // 当 /user/:id/posts 匹配成功
          // UserPosts 会被渲染在 User 的 <router-view> 中
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})

 2、创建主路由:在views文件夹下创建Main.vue

在router文件夹下的index.js配置主路由 

①创建主路由文件

 ②将原路由改写为嵌套路由【注意,子路由不可带/】

此时,App.vue的路由出口指的是主路由,因此还需在主路由Main.vue文件中提供子路由的路由出口【因为子路由会显示在主路由的内部】,打开Main.vue配置路由出口

扫描二维码关注公众号,回复: 14985046 查看本文章

3、此时访问页面,如下图所示说明嵌套路由配置完成

 

二、基于UI设计导航栏布局【样式美观】

1、根据UI图,到element官网查找对应的container布局容器

 本项目的UI样式基于左侧导航栏、顶栏和中间内容main实现,官方代码如下:

<el-container>
  <el-aside width="200px">Aside</el-aside>
  <el-container>
    <el-header>Header</el-header>
    <el-main>Main</el-main>
  </el-container>
</el-container>

将上述代码写入Main.vue主路由文件中,原先子路由出口写入<el-main>中

2、在src文件夹下的components文件夹中注册左侧导航栏组件CommonAside.vue,到element官网中选择样式,并根据官网文档封装属性进行修改,本项目选用的原生样式如下图所示:

官网原代码如下:

<el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
  <el-submenu index="1">
    <template slot="title">
      <i class="el-icon-location"></i>
      <span slot="title">导航一</span>
    </template>
    <el-menu-item-group>
      <span slot="title">分组一</span>
      <el-menu-item index="1-1">选项1</el-menu-item>
      <el-menu-item index="1-2">选项2</el-menu-item>
    </el-menu-item-group>
    <el-menu-item-group title="分组2">
      <el-menu-item index="1-3">选项3</el-menu-item>
    </el-menu-item-group>
    <el-submenu index="1-4">
      <span slot="title">选项4</span>
      <el-menu-item index="1-4-1">选项1</el-menu-item>
    </el-submenu>
  </el-submenu>
  <el-menu-item index="2">
    <i class="el-icon-menu"></i>
    <span slot="title">导航二</span>
  </el-menu-item>
  <el-menu-item index="3" disabled>
    <i class="el-icon-document"></i>
    <span slot="title">导航三</span>
  </el-menu-item>
  <el-menu-item index="4">
    <i class="el-icon-setting"></i>
    <span slot="title">导航四</span>
  </el-menu-item>
</el-menu>

将上述代码改写进入CommonAside.vue文件中,主要注意一级菜单和二级菜单写法(后续会有改写后的具体代码展示)

3、在主路由文件Main.vue中引入左侧导航栏,实现CommonAside.vue组件的引入、注册和使用

4、针对一级菜单和二级菜单的写法提供详细说明:

4.1 在script中的data部分写入一级菜单和二级菜单的数据,为后续数据渲染提供数据基础,定义数组menuData用于存放导航栏数据

 ①一级菜单数据写法

                //一级菜单写法

                {
                    path: '/teachingmanage',
                    name: 'teachingmanage',
                    label: '教研管理',
                    icon: 's-home',
                    url: 'TeachingManage/TeachingManage'
                },

②二级菜单数据写法

//二级菜单写法
                {
                    label: '研修管理',
                    icon: 's-home',
                    children: [
                        {
                            path: '/coursecenter',
                            name: 'coursecenter',
                            label: '课程中心',
                            icon: 's-home',
                            url: 'StudyManage/CourseCenter'
                        },
                        {
                            path: '/questionbank',
                            name: 'questionbank',
                            label: '题库管理',
                            icon: 's-home',
                            url: 'StudyManage/QuestionBank'
                        },

                    ]
                },

4.2 在script中的comupted部分定义判断有子菜单和无菜单的方法,为后续页面渲染数据奠定基础

 ①没有子菜单,判断item的children不存在,并将结果return

noChildren() {
            return this.menuData.filter(item => !item.children)
        },

②有子菜单,与没有子菜单的判断取反即可

        hasChildren() {
            return this.menuData.filter(item => item.children)
        }

4.3 在页面上渲染数据,实现导航栏数据的显示

 ①一级菜单页面渲染数据代码:

            <!-- 一级菜单 -->
            <!-- index用于确定选中的菜单项,是唯一标识 -->
            <!-- v-bind:(简写为:,用于属性绑定) -->
            <el-menu-item @click="clickMenu(item)" v-for="item in noChildren" :key="item.name" :index="item.name">
                <!-- `el-icon-${item.icon}`与data中的数据绑定,实现动态拼接 -->
                <i :class="`el-icon-${item.icon}`"></i>
                <span slot="title">{
   
   { item.label }}</span>
            </el-menu-item>

 ②二级菜单页面渲染数据代码:

<!-- 二级菜单 -->
            <el-submenu v-for=" item in hasChildren" :key="item.label" index="item.label">
                <!-- slot表示插槽 -->
                <template slot="title">
                    <i :class="`el-icon-${item.icon}`"></i>
                    <span slot="title">{
   
   { item.label }}</span>
                </template>
                <!-- 对子菜单进行渲染 -->
                <el-menu-item-group v-for="subItem in item.children" :key="subItem.path">
                    <el-menu-item @click="clickMenu(subItem)" :index="subItem.path">{
   
   { subItem.label }}</el-menu-item>
                </el-menu-item-group>
            </el-submenu>

4.4 CommonAside.vue文件的完整代码如下:

<template>
    <div>
        <el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
            :collapse="isCollapse">

            <!-- 一级菜单 -->
            <!-- index用于确定选中的菜单项,是唯一标识 -->
            <!-- v-bind:(简写为:,用于属性绑定) -->
            <el-menu-item @click="clickMenu(item)" v-for="item in noChildren" :key="item.name" :index="item.name">
                <!-- `el-icon-${item.icon}`与data中的数据绑定,实现动态拼接 -->
                <i :class="`el-icon-${item.icon}`"></i>
                <span slot="title">{
   
   { item.label }}</span>
            </el-menu-item>

            <!-- 二级菜单 -->
            <el-submenu v-for=" item in hasChildren" :key="item.label" index="item.label">
                <!-- slot表示插槽 -->
                <template slot="title">
                    <i :class="`el-icon-${item.icon}`"></i>
                    <span slot="title">{
   
   { item.label }}</span>
                </template>
                <!-- 对子菜单进行渲染 -->
                <el-menu-item-group v-for="subItem in item.children" :key="subItem.path">
                    <el-menu-item @click="clickMenu(subItem)" :index="subItem.path">{
   
   { subItem.label }}</el-menu-item>
                </el-menu-item-group>
            </el-submenu>

        </el-menu>
    </div>
</template>

<script>
export default {
    data() {
        return {
            //控制导航栏为展开模式
            isCollapse: false,

            //存放导航栏数据
            menuData: [
                //一级菜单写法

                {
                    path: '/teachingmanage',
                    name: 'teachingmanage',
                    label: '教研管理',
                    icon: 's-home',
                    url: 'TeachingManage/TeachingManage'
                },
                {
                    path: '/scientificmanage',
                    name: 'scientificmanage',
                    label: '科研管理',
                    icon: 's-home',
                    url: 'ScientificManage/ScientificManage'
                },


                //二级菜单写法
                {
                    label: '研修管理',
                    icon: 's-home',
                    children: [
                        {
                            path: '/coursecenter',
                            name: 'coursecenter',
                            label: '课程中心',
                            icon: 's-home',
                            url: 'StudyManage/CourseCenter'
                        },
                        {
                            path: '/questionbank',
                            name: 'questionbank',
                            label: '题库管理',
                            icon: 's-home',
                            url: 'StudyManage/QuestionBank'
                        },
                        {
                            path: '/examinationpaper',
                            name: 'examinationpaper',
                            label: '试卷管理',
                            icon: 's-home',
                            url: 'StudyManage/ExaminationPaperManage'
                        },
                        {
                            path: '/trainingmanage',
                            name: 'trainingmanage',
                            label: '培训管理',
                            icon: 's-home',
                            url: 'StudyManage/TrainingManage'
                        },
                    ]
                },

                //一级菜单写法

                {
                    path: '/evalutionmanage',
                    name: 'evalutionmanage',
                    label: '评价管理',
                    icon: 's-home',
                    url: 'EvalutionManage/EvalutionManage'
                },
                {
                    path: '/supervisioncenter',
                    name: 'supervisioncenter',
                    label: '监管中心',
                    icon: 's-home',
                    url: 'SupervisionCenter/SupervisionCenter'
                },
                {
                    path: '/usermanage',
                    name: 'usermanage',
                    label: '用户管理',
                    icon: 's-home',
                    url: 'UserManage/UserManage'
                },

            ]
        }
    },
    methods: {
        handleOpen() {

        },
        handleClose() {

        }
    },
    computed: {
        //没有子菜单,判断item的children不存在,并将结果return
        noChildren() {
            return this.menuData.filter(item => !item.children)
        },
        //有子菜单,与没有子菜单的判断取反即可
        hasChildren() {
            return this.menuData.filter(item => item.children)
        }


    }
}
</script>

运行项目,打开页面,发现导航栏菜单数据渲染成功【注意,为了说明el-main中的内容,下图展示时在url地址栏键入了home】

在下一节将介绍对导航栏样式的具体修改 

猜你喜欢

转载自blog.csdn.net/m0_56905968/article/details/128360465