本文主要介绍在多个页面存在相同部分时,如何提取公共组件然后在多个页面中导入组件重复使用来减少重复代码。在这基础上介绍了通过嵌套路由的方式来避免页面较多或公共部分较多的情况下,避免不断手动导入公共组件的麻烦,并且加快页面跳转的速度。
文章目录
- 本系列前文传送门
- 一、场景说明
- 二、公共组件
- 提取公共组件
- 三、嵌套路由
在前面的文章中,我们已经介绍过如何编写多个页面,然后在上一篇文章中,我们为首页实现了一个导航栏。
现在考虑这样一个场景,我们有Home
和About
两个页面,为了用户在各个页面之间跳转方便,有良好的网页浏览体验,我们考虑在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 {
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 pageh1>
div>
template>
<script>
import MyHeader from './MyHeader.vue';
export default {
components: { MyHeader },
}
script>
我们回到浏览器中,就可以看到首页和About
页面显示如下,两个页面之间可以非常快速地跳转:
我们刚才的做法,是直接把导航栏作为一个公共组件,然后在用到的页面中导入使用。但如果随着我们的项目规模变大,网站页面增多,我们如果每写一个页面都需要导入一次导航栏组件,就有点重复代码的味道了。
为此,我们可以使用嵌套路由来解决,我们再次看到两个页面的组成如下:
/home /about
+------------------+ +-----------------+
| Header | | Header |
| +--------------+ | | +-------------+ |
| | Home | | +------------> | | About | |
| | Content | | | | Content | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
嵌套路由的用法就是:
代表不同的部分vue-router
实例Router
的children
参数传入,由vue-router
渲染不同的部分来替换
。比如这里的/home
和/about
的公共路径就是/
,公共代码是导航栏部分代码,所以应该在路径/
对应的代码中放入导航栏组件代码,然后用
代表Home
和About
两个页面中各自独有的部分。
因为现在路径/
直接对应的是HelloWorle.vue
,导航栏代码和首页代码暂时耦合在一起,所以我们需要先把原本的HelloWolrd.vue
和About.vue
拆成三个代码文件:Layout.vue
, HellWorld.vue
和About.vue
,三个文件代码如下:
HellWorld.vue
<template>
<div id="app">
<h1>This is a Home pageh1>
div>
template>
About.vue
<template>
<div id="app">
<h1>This is a About pageh1>
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
就会将
替换成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>
回到我们的浏览器,尝试点击导航栏的「产品」就可以跳转到路径/product
对应的Product
页面,页面内容如下:
可以看到我们不需要在product.vue
中添加导航栏的代码就可以让页面平等地拥有相同的导航栏,这就是嵌套路由的好处。当我们的页面相同部分的内容比较多,提取的公共组件也比较多,这种不需要将各个公共组件依次手动导入的做法,优势就会更加明显。
甚至我们会发现,现在点击导航栏在各个页面之间跳转的速度极快,浏览器不需要重新加载页面资源就可以实现页面切换,这就是我们之前提到的vue-router
的router-view
和router-link
进行跳转的好处。(●ˇ∀ˇ●)
写文不易,如果对你有帮助的话,来一波点赞、收藏、关注吧~