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

2023-10-29

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

本系列前文传送门


一、场景说明

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

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

/home                                 /about
+------------------+                  +-----------------+
| Header           |                  | Header          |
| +--------------+ |                  | +-------------+ |
| | Home         | |  +------------>  | | About       | |
| | Content      | |                  | | Content     | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

二、公共组件

当我们需要在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>标签 */
    >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>

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

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

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

<template>
    <div id="app">
        <MyHeader></MyHeader>
        <h1>This is a About page</h1>
    </div>
</template>

<script>
import MyHeader from './MyHeader.vue';
export default {
    components: { MyHeader },
}

</script>

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

三、嵌套路由

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

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

/home                                 /about
+------------------+                  +-----------------+
| Header           |                  | Header          |
| +--------------+ |                  | +-------------+ |
| | Home         | |  +------------>  | | About       | |
| | Content      | |                  | | Content     | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

嵌套路由的用法就是:

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

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

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

  • HellWorld.vue
<template>
    <div id="app">
        <h1>This is a Home page</h1>
    </div>
</template>
  • About.vue
<template>
    <div id="app">
        <h1>This is a About page</h1>
    </div>
</template>
  • 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>

之后在渲染首页的时候,vue-router就会将<router-view>替换成HelloWorld.vue的内容;在渲染About页面的时候,vue-router就会将<router-view>替换成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 page</h1>
    </div>
</template>
  • src/router/index.js代码改动:
    在这里插入图片描述

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

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

本系列下一篇文章传送门

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

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

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

  • AngularJS 仅在解析时返回两个 http get 请求

    我有一个 Angular 应用程序 在控制器中我需要调用一个发出两个 http get 请求的函数 并且我需要这个函数在解析这些值时返回这些值 我无法在 routeProvider 中解析它们 因为此函数需要在同一控制器中获取值 我展示了控
  • Canvas drawImage 内联 svg 在 Firefox 上不起作用

    这是一个例子 它采用 svg 并将其转换为画布 http jsfiddle net Na6X5 944 http jsfiddle net Na6X5 944 var can document getElementById canvas1
  • 如何从客户端设置 HTMLEditorExtender HTML

    我无法让它工作 这是我在另一个线程中找到的代码 但它对我不起作用 我得到 set content 不是函数 find set content whatever 这仍然有效吗 我还尝试设置它扩展的文本框的值 尝试设置两者的 InnerHtml
  • 等待两个异步函数完成,然后在 Node.js 中继续

    我正在 Node js 中开发一个应用程序 其中调用异步函数两次 并将值分配给全局变量 问题是我想使用这两个调用的结果来做其他事情 但是这个其他事情不会等待结果被分配 这是我的代码 var a var b let x abcd foo x
  • 如何使用 Angularjs 检查模块中的指令或控制器是否可用

    在 angularjs 中 给定一个模块 如何检查给定一个模块是否存在指令 控制器 我有一个模块 我想知道是否已加载某些特定指令 下面是一些示例代码 var module angular module myModule check if c
  • 在 PHP 中合并文件块

    出于教育目的 我想创建文件块上传 你们怎么知道所有块何时上传 我试图从temp并重命名它们 使它们按正确的顺序排列 然后与最后一个块将它们合并在一起 然而 我猜最后发送的并不是最后收到的 所以fopen on chunks 失败 因为它们尚
  • 在 HTML5 中堆叠多个画布

    我试图使用相互堆叠的四块画布 但除了顶部画布的内容外 它们的内容不会显示 我按照我希望它们显示的顺序将 z index 值放入其中 但只有最上面的一个显示内容 它们的位置是绝对的 z 索引是 1 2 3 和 4 是否还有其他原因导致它们不显
  • 如何从谷歌地图中的纬度和经度获取地址位置? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 所以我有纬度和经度就像44 4647452 and 7 3553838 我需要获得如下地址 米兰 意大利 str 肯尼迪 89 我怎样才能
  • React Native 中循环 Json 并显示

    How do I go about looping the result i retrieved from Json render function console log this state list contents
  • 如何在不知道id的情况下从内页获取父iframe元素?

    让我们想象一下我有这样的东西 div div test html 是空页面 自定义hash属性始终具有不同的值 出于安全原因两个页面位于同一域 iframe 元素的数量和顺序是随机的 我的问
  • 用 JavaScript 改变文本颜色?

    我想在单击按钮时更改标题的颜色 这是我的代码 但它不起作用 我不明白为什么不 var about function init about document getElementById about innerHTML about style
  • React:在哪里扩展对象原型

    我使用创建了一个纯 React 应用程序创建反应应用程序 https github com facebookincubator create react app 我想延长String类并在一个或多个组件中使用它 例如 String prot
  • 如何使用 HTML5 在画布上绘制心电图监视器?

    我尝试使用canvas html5绘制心电图系统 几乎我即将完成我的波浪正在移动 但不是连续地重复 但我想绘制波浪是从左到右连续移动的 下面的链接是示例 Ex https www youtube com watch v wuwBfSpVEg
  • 地理编码服务与 gMap 搜索之间的差异结果

    我想获取此地址的纬度和经度 Boulevard de la Marne Zone industrielle COULOMMIERS 77120 France 我将 api 添加到我的页面 当我使用 gmaps 时 结果很好 但是当我想通过
  • JSON.stringify 对于大型对象来说非常慢

    我在 javascript 中有一个非常大的对象 大约 10MB 当我对其进行字符串化时 需要很长时间 因此我将其发送到后端并将其解析为一个对象 实际上是带有数组的嵌套对象 这也需要很长时间 但这不是我们在这个问题中的问题 问题 我怎样才能
  • 在 jQuery 中获取最接近元素的形式

    我编写了这个 js jquery 脚本来检查表单中的所有复选框 它工作得很好 但是这会检查页面上的所有复选框 无论它们是什么表单包装器 这是函数 function toggleCheck state var checkboxes jQuer
  • 仅在页面加载时执行 Javascript,而不是回发 (SharePoint)

    我正在尝试在 SharePoint 网站上的自定义页面上加载页面时执行一些 JavaScript 它使用当前用户填充人员选择器 问题是代码也在回发时执行 这是我不希望的 因为它会重置人员选择器的任何更改 我尝试过使用if IsPostBac
  • 是否可以对 Flexbox 插入、删除和项目位置进行动画处理?

    这个问题最初是在 2012 年提出的 https stackoverflow com questions 11106876 is it possible to animate flexbox inserts removes但是提供的答案并未
  • 何时使用node.js、sinatra、rails? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 这 3 种语言 框架的最佳用途是什么 混合所有 或 2 个 有用吗 如果您正在构建一个完整的 Web 应用程序 您可能应该使用 Rails 因为
  • 解析函数是否异步传递给 Promise 执行器?

    我有以下代码 function myPromiseFunc return new Promise resolve gt resolve Promise resolve 123 据我们所知Promise resolve方法立即用普通值解析 P

随机推荐

  • h5上下滑动动画效果(vue)

    1 详情介绍 图片可以使用网络图片 根据请求过来的图片来获取高度要控制滑动的位置 可以换成视频 要实现滑动播放视频的效果 并且可以在上面添加一些其他的功能 白色背景区域可以展示对应的数据 具体效果看文章末尾 2 编码介绍 template部
  • UNIX环境高级编程 学习笔记 第十九章 伪终端

    终端登录是经由终端设备进行的 终端设备天然提供终端语义 在终端和运行程序之间有一个终端行规程 通过该规程我们能设置终端特殊字符 如退格 行删除 中断等 但当一个登录请求到达网络连接时 终端行规程并不是自动被加载到网络连接和登录shell之间
  • VSCode在linux服务器下launch.json和tasks.json等文件配置

    前言 用win下的VSCode远程连接linux服务器后 就可以用VSCode运行linux下代码了 在编译运行代码前 按照VSCode的要求 我们要给编译和执行操作分别配置一堆参数 这就是launch json和tasks json配置的
  • Android WebView加载优化,Android WebView 优化页面加载效果

    目前带有Web功能的APP越来越多 为了能够更好的使用WebView展示页面 可以考虑做相关的优化 WebView 缓存 资源文件本地存储 客户端UI优化 目前webapp越来越多 体验也越来越好 为了能够更好的使用WebView展示出流畅
  • 深入解析Spring使用枚举接收参数和返回值机制并提供自定义最佳实践

    Spring对应枚举传参 返回值默认是用字面量实现的 实际情况更复杂 而 阿里巴巴Java开发手册 规定接口返回值不可以使用枚举类型 包括含枚举类型的POJO对象 为此 本文探究了Spring内部对枚举参数的传递和处理机制 并提供了一套自定
  • JULES模型

    参考文献 1 2020 Calibrating soybean parameters in JULES 5 0 from the US Ne2 3 FLUXNET sites and the SoyFACE O 3 expe 流程 2 20
  • 排序算法详解

    概述 冒泡排序 应用1 把数组排成最小的数 应用2 移动零到数组末尾 排序算法是一类非常经典的算法 说来简单 说难也难 刚学编程时大家都爱用冒泡排序 随后接触到选择排序 插入排序等 历史上还有昙花一现的希尔排序 公司面试时也经常会问到快速排
  • 二维数组. 转置矩阵

    转自 二维数组 转置矩阵 知乎 二维数组 转置矩阵 Diamon 2 人赞同了该文章 867 转置矩阵 给你一个二维整数数组 matrix 返回 matrix 的 转置矩阵 矩阵的 转置 是指将矩阵的主对角线翻转 交换矩阵的行索引与列索引
  • 如何让“ChatGPT自己写出好的Prompt的“脚本在这里

    写个好的Prompt太费力了 在网上 你可能会看到很多人告诉你如何写Prompt 需要遵循各种规则 扮演不同的角色 任务明确 要求详细 还需要不断迭代优化 写一个出色的Prompt需要投入大量的时间和精力 甚至有一些公开的Prompt的开源
  • java前后端交互_Java之前后端数据交互

    1 前台发送数据到服务端 以及接受后台数据 前台发送数据到服务端 有两种方法 1 使用 表单发送同步请求 参数inputStr 参数intputInt 2 使用ajax发送异步请求 发送的数据为json对象 参数username 参数pas
  • 【报童模型】随机优化问题&&二次规划

    面对需求的不确定性 报童模型是做库存优化的常见模型 而标准报童模型假设价格是固定的 此时求解一个线性规划问题 可以得到最优订货量 这种模型存在局限性 因为现实世界中价格与需求存在一定的关系 本文假设需求q是价格p的线性函数 基于历史需求数据
  • 面试之你为什么从上家公司离职

    在上家公司 你为什么离职 请相信 百分之八十的面试官 要么是HR要么是技术负责人 或多或少都会问到的问题 如果问你这个问题 你该如何回答 举几个不太恰当的例子 大家尽量不要用下面的理由 我是感觉不太好 1 因为上家公司不能办公室谈恋爱 我就
  • centos7.0中搭建dhcp服务器

    一 dhcp 二 配置dhcp的方法 1 安装dhcp服务器 使用命令 vpm qa dhcp 查看一下dhcp有没有安装 如果没安装将不会有任何提示信息 如果安装好了 将会返回dhcp的版本号 可以看到我已经安装好了 在centos7的安
  • Swagger2介绍及使用

    项目中整合Swagger2 1 什么是swagger2 2 常用注解 3 项目中整合Swagger2 3 1 引入Swagger2依赖 3 2 编写swgger2配置类代码 3 3 在需要测试的模块中引入有swagger2的模块坐标 3 4
  • QT 智能提示设置

    关于QT的智能提示 有两点 一 默认只能在Ctrl Space或打 会自动转成 gt 的时候会出现 由于Ctrl Space默认在我电脑上是输入法的切换 所以一直以为没这个功能 敲代码时特别郁闷 于是在QT Creator中的Tool gt
  • 离散事件仿真原理DES

    参考 SYSTEM SIMULATION AND OPTIMIZATION 目录 1 系统仿真原理 1 1系统 模型和系统仿真 1 2系统仿真分类 1 2 1 蒙特卡洛仿真 Monte Carlo Simulation 1 2 2 离散系统
  • 傅里叶变换的一些总结

    傅里叶变换的一些总结 1 三角函数的正交性 三角函数系 1 c o s 0 x
  • 2023年Java面试笔试题

    Java 第一部分 1 什么叫多态 多态是同一个行为具有多个不同表现形式或形态的能力 即同一个接口采用不同的实例而执行不同的操作 2 以下哪个选 项属于多态存在的必要条件 A 继承 B 重写 C 父类引用指向子类对象 D 以上都是 多态存在
  • C语言代码规范

    1 排版 1 1 程序块要采用缩进风格编写 缩进的空格数为4个 1 2 相对独立的程序块之间 变量说明之后必须加空行 1 3 较长的语句 gt 80字符 要分成多行书写 长表达式要在低优先级操作符处划分新行 操作符放在新行之首 划分出的新行
  • 「网页开发|前端开发|Vue」06 公共组件与嵌套路由:让每一个页面都平等地拥有导航栏

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