• 「网页开发|前端开发|Vue」06 公共组件与嵌套路由:让每一个页面都平等地拥有导航栏


    本文主要介绍在多个页面存在相同部分时,如何提取公共组件然后在多个页面中导入组件重复使用来减少重复代码。在这基础上介绍了通过嵌套路由的方式来避免页面较多或公共部分较多的情况下,避免不断手动导入公共组件的麻烦,并且加快页面跳转的速度。

    本系列前文传送门


    一、场景说明

    前面的文章中,我们已经介绍过如何编写多个页面,然后在上一篇文章中,我们为首页实现了一个导航栏

    现在考虑这样一个场景,我们有HomeAbout两个页面,为了用户在各个页面之间跳转方便,有良好的网页浏览体验,我们考虑在About页面也增加导航栏,如下:

    /home                                 /about
    +------------------+                  +-----------------+
    | Header           |                  | Header          |
    | +--------------+ |                  | +-------------+ |
    | | Home         | |  +------------>  | | About       | |
    | | Content      | |                  | | Content     | |
    | +--------------+ |                  | +-------------+ |
    +------------------+                  +-----------------+
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    二、公共组件

    当我们需要在About页面中也增加一个相同的导航栏时,我们当然可以直接拷贝一份代码到About页面的代码中,但显然我们不会这么做。

    在编程语言中,为了应对相同代码在多处使用的情况,会有函数、类、模块的设计,而在前端框架的设计中,会通过将公共部分或者说相同的代码部分,提取成独立的组件,然后在多处重复使用。

    提取公共组件

    我们将上次开发好的含导航栏的首页代码复制一份,然后命名为MyHeader.vue如下:

    <template>
        <div id="app">
            <div class="header">
                <div class="content-main">
                    <div class="logo">
                        <img src="../assets/logo.png" />
                        <span>我的网站span>
                    div>
                    <ul class="nav-items">
                        <li v-for="item in  routerList " :key="item.id">
                            <el-link @click="$router.push({ path: item.path })" type="info">
                                {{ item.name }}
                            el-link>
                        li>
                    ul>
                    <div class="user">
                        <el-button size="mini">注册el-button>
                        <el-button size="mini">登录el-button>
                    div>
                div>
            div>
        div>
    template>
    
    <script>
    export default {
        data() {
            return {
                routerList: [
                    {
                        path: "/",
                        name: "首页",
                    },
                    {
                        path: "/product",
                        name: "产品",
                    },
                    {
                        path: "/about",
                        name: "关于我们",
                    }
                ]
            }
        }
    }
    
    script>
    
    <style>
    li {
        display: inline-block;
        margin: 20px;
    }
    
    .nav-items {
        display: inline-block;
    }
    
    .logo {
        display: inline-block;
        cursor: pointer;
        margin-right: 46px;
    
        /* >img 表示 class='logo'的元素中的标签 */
        >img {
            width: 20px;
            height: 20px;
            vertical-align: middle;
            margin-right: 10px;
        }
    
        >span {
            font-weight: bold;
            vertical-align: middle;
        }
    }
    
    .user {
        display: inline-block;
        margin-left: 46px;
    
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    然后在原本的首页代码HelloWorld.vue中将导航栏代码作为组件导入,代码改动如下:
    在这里插入图片描述

    由于我们还没有删除原本存在的导航栏代码,所以现在如果成功导入一个新的导航栏后,首页应该要有两个导航栏,我们到浏览器验证这一点,如下:
    在这里插入图片描述

    并且确认两个导航栏的跳转功能都符合预期,然后我们就可以将首页代码HelloWorld.vue中的导航栏代码删除,然后在About代码中,重复我们刚才导入导航栏组件的操作,About.vue代码如下:

    <template>
        <div id="app">
            <MyHeader>MyHeader>
            <h1>This is a About pageh1>
        div>
    template>
    
    <script>
    import MyHeader from './MyHeader.vue';
    export default {
        components: { MyHeader },
    }
    
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    我们回到浏览器中,就可以看到首页和About页面显示如下,两个页面之间可以非常快速地跳转:
    在这里插入图片描述
    在这里插入图片描述

    三、嵌套路由

    我们刚才的做法,是直接把导航栏作为一个公共组件,然后在用到的页面中导入使用。但如果随着我们的项目规模变大,网站页面增多,我们如果每写一个页面都需要导入一次导航栏组件,就有点重复代码的味道了。

    为此,我们可以使用嵌套路由来解决,我们再次看到两个页面的组成如下:

    /home                                 /about
    +------------------+                  +-----------------+
    | Header           |                  | Header          |
    | +--------------+ |                  | +-------------+ |
    | | Home         | |  +------------>  | | About       | |
    | | Content      | |                  | | Content     | |
    | +--------------+ |                  | +-------------+ |
    +------------------+                  +-----------------+
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    嵌套路由的用法就是:

    • 在两个具体路径的共同路径对应的页面代码中放入公共部分代码
    • 然后使用代表不同的部分
    • 最后将不同的部分作为vue-router实例Routerchildren参数传入,由vue-router渲染不同的部分来替换

    比如这里的/home/about的公共路径就是/,公共代码是导航栏部分代码,所以应该在路径/对应的代码中放入导航栏组件代码,然后用代表HomeAbout两个页面中各自独有的部分。

    因为现在路径/直接对应的是HelloWorle.vue,导航栏代码和首页代码暂时耦合在一起,所以我们需要先把原本的HelloWolrd.vueAbout.vue拆成三个代码文件:Layout.vue, HellWorld.vueAbout.vue,三个文件代码如下:

    • HellWorld.vue
    <template>
        <div id="app">
            <h1>This is a Home pageh1>
        div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • About.vue
    <template>
        <div id="app">
            <h1>This is a About pageh1>
        div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • Layout.vue
    <template>
        <div id="app">
            <MyHeader>MyHeader>
            <router-view>router-view>
        div>
    template>
    
    <script>
    import MyHeader from './MyHeader.vue';
    export default {
        components: { MyHeader },
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    之后在渲染首页的时候,vue-router就会将替换成HelloWorld.vue的内容;在渲染About页面的时候,vue-router就会将替换成About.vue的内容。

    但是我们需要跳转vue-router实例化时传入的routes参数才能实现这个效果。
    于是我们回到src/router/index.js进行如下代码调整:
    在这里插入图片描述

    回到浏览器,我们可以看到页面已经如我们预期的那样,在两个页面中都展示导航栏了,如下:
    在这里插入图片描述
    在这里插入图片描述

    之后如果我们再添加新的页面,比如添加一个产品页面Product来对应路径/product,这个改动只需要增加一个Product.vue,然后在src/router/index.js中增加一个路径对应关系,如下:

    • Product.vue
    <template>
        <div id="app">
            <h1>This is a Product pageh1>
        div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • src/router/index.js代码改动:
      在这里插入图片描述

    回到我们的浏览器,尝试点击导航栏的「产品」就可以跳转到路径/product对应的Product页面,页面内容如下:
    在这里插入图片描述
    可以看到我们不需要在product.vue中添加导航栏的代码就可以让页面平等地拥有相同的导航栏,这就是嵌套路由的好处。当我们的页面相同部分的内容比较多,提取的公共组件也比较多,这种不需要将各个公共组件依次手动导入的做法,优势就会更加明显

    甚至我们会发现,现在点击导航栏在各个页面之间跳转的速度极快,浏览器不需要重新加载页面资源就可以实现页面切换,这就是我们之前提到的vue-routerrouter-viewrouter-link进行跳转的好处。(●ˇ∀ˇ●)

    本系列下一篇文章传送门

    写文不易,如果对你有帮助的话,来一波点赞、收藏、关注吧~👇

  • 相关阅读:
    手记:把代码上传到Gitee等远程仓库的过程记录及常见问题
    基于智能优化算法的交通流模拟器(Matlab代码实现)
    vue-json-editor
    新160个CrackMe分析-第2组:11-20(下)
    ChatGLM-6B下载安装
    -数字之和-
    出口日本的无线产品是做MIC认证还是TELCE认证?有什么区别?
    SSM框架学习——SpringBoot之整合第三方技术
    java多线程-单例模式与多线程
    qnx shell sh ,linux shell bash
  • 原文地址:https://blog.csdn.net/qq_41785288/article/details/132704392