「Vue|网页开发|前端开发」02 从单页面到多页面网站:使用路由实现网站多个页面的展示和跳转

本文主要介绍如何使用路由控制来实现将一个单页面网站扩展成多页面网站,包括页面扩展的逻辑,vue的官方路由vue-router的基本用法以及扩展用法

文章目录

  • 本系列前文传送门
  • 一、场景说明
  • 二、基本的页面扩展
    • 页面扩展是在扩什么
    • 创建新页面的代码,让页面内容变化起来
    • 对地址栏的地址格式进行一个优化
  • 三、避免页面频繁重新加载的路由用法
    • `<router-view/>`的作用
    • `<router-link>`标签
    • `<router-link>`标签作用
  • 四、路由用法扩展:更多定制化的路由配置场景
    • 动态路由实现详情页展示
  • 五、控制路由跳转的API
  • 本系列下一篇文章传送门

本系列前文传送门

  • 「Vue|网页开发|前端开发」01 快速入门:快速写一个Vue的HelloWorld项目

一、场景说明

我们在进行网站开发的时候,大多数都是需要有多个页面展示不同内容或者提供不同功能。每个页面单独启动一个项目的做法不太现实,实际业务中是一个项目中,一个页面对应项目代码中一个代码文件,然后通过浏览器地址的不同后缀(比如/home, /about, /prodcut, /center等等)来对应到不同的代码文件,进而在浏览器上展示不同的内容和提供不同的功能。

二、基本的页面扩展

页面扩展是在扩什么

在前文介绍如何快速开始一个项目时,我们已经探索到了页面渲染的逻辑,即:

  • 浏览器根据地址栏输入的地址,会得到一个path
  • 我们在代码里指明某个path对应某个component
  • 我们在component编写我们要展示的内容和功能

就完成了从代码到浏览器内容的关联和渲染展示。

当我们要跳转到一个新的页面的时候,一般地址栏的地址会跟随着变化,会有一个新的地址,即会有一个新的path
所以,当我们要增加一个新的页面的时候,其实就是新增一个从代码到浏览器地址的关联关系。即,在src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'Vue.use(Router)export default new Router({routes: [{path: '/',name: 'HelloWorld',component: HelloWorld}]
})

改成

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'Vue.use(Router)export default new Router({routes: [{path: '/',name: 'HelloWorld',component: HelloWorld},{path: '/about',name: 'About',component: HelloWorld }]
})

这里我们在routes的值中增加了一个元素,即增加了一个从浏览器地址后缀/about关联到代码HelloWorld的关联关系,只不过我们这里关联的代码没有额外写,而是直接再次用了HelloWorld页面的代码。

现在我们的项目就有两个页面了,可以分别通过浏览器地址栏输入http://localhost:8080/#/http://localhost:8080/#/about来访问两个页面。

由于我们使用了同样的代码来展示两个页面,所以看到的页面内容其实是一样的。打个比方说,如果我们的项目现在是一本两页的书,那么这两页的内容是一样的。

可以确定的是,我们现在确实是两个页面,而不是一个页面。如果需要验证这一点,可以把我们刚才的代码改动先注释掉或者删掉,然后直接访问http://localhost:8080/#/about,可以看到页面的内容其实跟HelloWorld页面内容不一样,而是下面的仅有一个logo图片的页面:
在这里插入图片描述

创建新页面的代码,让页面内容变化起来

现在我们需要编写一个新的代码来对应路径/about,使得浏览器展示我们想展示的内容。因为我们的代码是由框架生成的标准化代码,所以这件事变得很简单,我们可以这样操作:

  • 直接复制一份HelloWorld.vue代码副本
  • 然后将副本命名为About.vue
  • src/router/index.js中导入About
  • 再将路径/about对应的代码从HelloWorld改成About

这样我们就完成了两个路径对应两个页面,两个页面用的是不同代码。然后我们修改About.vue里面的内容,让我们可以直观地从浏览器展示的内容观察到这一点。
进入App.vue,然后修改底下msg变量的值

export default {name: 'HelloWorld',data () {return {msg: 'Hello Vue World!'}}
}

改成

export default {name: 'HelloWorld',data () {return {msg: 'About Vue World!'}}
}

保存后,重新打开浏览器可以看到我们/about对应的页面内容已经发生变化:
在这里插入图片描述

至此,我们就完成了网站页面从单页面网站升级成多页面网站的过程~ (●ˇ∀ˇ●)

对地址栏的地址格式进行一个优化

我们可以看到我们的两个页面的地址栏输入是http://localhost:8080/#/http://localhost:8080/#/about,所以我们目前的地址栏格式是http://localhost:8080/#/XXXXX

这种格式其实我们在日常浏览其他网站的时候并不常见,更常见的格式是http://localhost:8080/about,也就是我们可以优化一下地址格式,尝试将#/从地址中移除。

要实现这一点我们只需要在src/router/index.js中,在创建router实例的时候,指定一个mode参数,如下:

export default new Router({mode: "history",routes: [{path: '/',name: 'HelloWorld',component: HelloWorld},{path: '/about',name: 'About',component: About}]
})

重新打开浏览器,就可以看到地址格式已经是我们希望的样子了:
在这里插入图片描述

三、避免页面频繁重新加载的路由用法

到这里,我们可以做一个回顾,我们在给一个网站"安装路由器"的时候都做了哪些事情?

  • 首先我们使用了vue的官方路由包vue-router,这个包在一开始初始化项目时通过命令行提示选择了Yes完成了安装。如果不是这样,则需要通过npm install vue-router进行安装。
  • 然后我们出于文件结构清晰的考虑,会有一个router文件夹,文件夹下是router的入口index.js(框架初始化时已经自动生成)。
  • router/index.js中生成了路由器Router实例,其中指定了浏览器地址(path)到代码(component)的关联关系,由此完成了引导浏览器根据地址栏输入的地址将项目中对应的代码渲染到浏览器中进行展示的工作。
  • 然后我们去扩展地址(path)跟代码(component)的关联关系来增加网站能够展示的页面数量。

至此我们接触了vue路由相关的概念:

  • 官方路由包:vue-router
  • 路由文件入口:src/router/index.js
  • 生成的路由器实例:Router()
  • 在项目应用中导入路由src/main.js[line:10] new Vue(el, router, components, template)
  • 在页面中使用路由:src/App.vue[line:4] <router-view/>

<router-view/>的作用

<router-view>就是在页面渲染的时候,通过地址栏的path在我们指定的路径 -> 代码的关联关系中找到需要渲染的代码,然后将代码的内容替换到<router-view>的位置上。通过这一点我们可以进一步理解我们目前看到的页面内容:

  • 我们在HelloWorld中定义了一些文本和一些超链接,所以渲染时<router-view>会替换成这些文本和超链接,于是我们便看到浏览器中的内容。
    在这里插入图片描述
  • 当我们输入一个在路径 -> 代码关联关系中没有指定的路径,比如/nothing,我们会看到文本和链接都不见了,取而代之的是一片空白,就可以理解成<router-view>没有找到要替换的代码,就是空,于是<router-view>的位置就是一片空白。
    在这里插入图片描述
  • /nothing页面中,虽然文本和超链接不见了,但是logo图片还在,我们去看这个logo图片代码的位置就可以知道,这是因为logo图片代码是在<router-view>上方单独的代码,而不是它去替换的内容,所以每个页面都能看到logo图片。

<router-link>标签

除了<router-view>标签之外,如果去看官网文档或者其他资料,一般会提到另一个标签叫做<router-link>

<router-link>其实就是替代原生的HTML超链接标签<a>存在的,写法如下:

<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>

<router-link>标签作用

<router-link> text <router-link/>当然不只是给<a> text </a>的另一种写法,必然是还有其他好处才会出现。

所以它的好处就是能够使得vue-router可以在不重新加载页面的情况下更改 URL,处理 URL 的生成以及编码。减少页面的重新加载就可以提高网站的性能和用户在浏览和跳转过程中的体验,这才是我们去用<router-link>代替<a>所希望得到的。

四、路由用法扩展:更多定制化的路由配置场景

动态路由实现详情页展示

我们在实际开发过程中,一个页面展示的内容布局是不变的,只是页面的数据不同而已,比如:

  • 博客网站的博文详情页
  • 电商网站的商品详情页
  • 视频网站的视频播放页

关于详情页这种只是数据变化的页面,我们的实现方法一般是拿到数据之后将数据展示到对应的位置上。至于数据可以是在页面跳转前将数据传入,常见于我们说的MVC架构中;也可以是从网页请求中获取对应的数据参数,然后进行数据请求得到数据,常见于前后端分离的架构。

如果我们是从网页请求中获取的数据参数,则我们可以常见到如下两种请求方式:

  • 参数作为url请求传入:http://localhost:8080/user?user_id=1
  • restful的方式,作为路由的一部分,由路由逻辑按照指定模式去匹配获取:http://localhost:8080/user/1

如果要实现http://localhost:8080/user/1这种方式,我们可以可以使用vue-router的动态路由参数,将router的配置修改如下:

export default new Router({mode: "history",routes: [{// 动态字段以冒号开始path: '/user/:id',name: 'UserDetail',component: UserDetail}
})

除此之外,还有一些其他的常见用法:

  • 不同路径指向相同页面:

    • 比如//home(甚至/index)都指向HomePage
    • { path: '/', component: Homepage, alias: '/home' }
    • { path: '/', component: Homepage, alias: ['/home', '/index'] }
  • 嵌套路由:

    • 只替换某些部分的内容,公共内容不变,减少重复代码
    • /user/:id/profile:显示用户个人信息
    • /user/:id/posts :显示用户发布的文章
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},],},
]
  • 懒加载:
    • 只有当路由被访问的时候才加载对应组件
    • 防止页面加载过慢以及构建应用时打包的js包过大
    • 不是懒加载的写法:import HelloWorld from '@/components/HelloWorld'
    • 懒加载写法一:const HelloWorld = ()=>import('@/components/HelloWorld')
    • 懒加载写法二(异步):{ path: '/', name: 'HelloWorld', component: resolve => require(['@/components/HelloWorld'], resolve) }

五、控制路由跳转的API

我们也可以通过在组件中调用Router API来实现路由的跳转、回退等功能。

  • 跳转到其他页面:

    • API写法:this.$router.push('/about')
    • 等价于<router-link>形式:<router-link :to="/about">跳转到About</router-link>
    • 等价URL: /about
  • 带参数跳转:

    • this.$router.push({ path: '/search', query: { keyword: 'vue' } })
    • 等价URL:/search?keyword=vue
  • 获取参数:this.$route.query.keyword // 得到值:vue

  • 带锚点hash(#)跳转:

    • router.push({ path: '/about', hash: '#team' })
    • 等价URL:/about#team
  • 使用params跳转

    • 可以让参数不显示在URL上,防止一些信息泄露
    • this.$router.push({ name: 'user', params: { username: 'aki' } })
  • 获取params:this.$router.params.username // 得到值: aki

  • 返回上一页:this.$router.go(-1)

  • 后退两页:this.$router.go(-2)

掌握了以上内容基本就可以解决实际业务开发中的大部分场景,第四部分的API不需要记忆,只需要记住可以通过编写代码逻辑的形式来控制路由即可。

快去试试搭建自己的多页面网站吧~


本系列下一篇文章传送门

  • 「CSS|前端开发|页面布局」03 开发网站所需要知道的CSS:如何实现你想要的页面布局

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/110832.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试题-React(七):React组件通信

在React开发中&#xff0c;组件通信是一个核心概念&#xff0c;它使得不同组件能够协同工作&#xff0c;实现更复杂的交互和数据传递。常见的组件通信方式&#xff1a;父传子和子传父 一、父传子通信方式 父组件向子组件传递数据是React中最常见的一种通信方式。这种方式适用…

SpringBoot异步方法支持注解@Async应用

SpringBoot异步方法支持注解Async应用 1.为什么需要异步方法&#xff1f; 合理使用异步方法可以有效的提高执行效率 同步执行(同在一个线程中): 异步执行(开启额外线程来执行): 2.SpringBoot中的异步方法支持 在SpringBoot中并不需要我们自己去创建维护线程或者线程池来…

C#_进程单例模式.秒懂Mutex

什么是Mutex? 可以定义调用线程是否具有互斥性&#xff0c;程序创建者拥有控制权&#xff0c;相反只能引用程序。 参数1&#xff1a;如果是程序创建者&#xff0c;就获得控制权。 参数2&#xff1a;名称&#xff0c;可使用GUID生成。 参数3&#xff1a;out 返回值&#xf…

Linux下套接字TCP实现网络通信

Linux下套接字TCP实现网络通信 文章目录 Linux下套接字TCP实现网络通信1.引言2.具体实现2.1接口介绍1.socket()2.bind()3.listen()4.accept()5.connect() 2.2 服务器端server.hpp2.3服务端server.cc2.4客户端client.cc 1.引言 ​ 套接字(Socket)是计算机网络中实现网络通信的一…

1688API技术解析,实现获得1688商品详情

要实现获得1688商品详情&#xff0c;你需要使用1688 API。1688 API是阿里巴巴旗下的开放平台&#xff0c;它提供了一套丰富的接口&#xff0c;可以让开发者通过编程的方式获取到1688网站上的商品信息。 首先&#xff0c;你需要在阿里开放平台注册一个账号&#xff0c;并创建一…

【NLP的python库(01/4) 】: NLTK

一、说明 NLTK是一个复杂的库。自 2009 年以来不断发展&#xff0c;它支持所有经典的 NLP 任务&#xff0c;从标记化、词干提取、词性标记&#xff0c;包括语义索引和依赖关系解析。它还具有一组丰富的附加功能&#xff0c;例如内置语料库&#xff0c;NLP任务的不同模型以及与S…

深眸科技创新赋能视觉应用产品,以AI+机器视觉解决行业应用难题

随着工业4.0时代的加速到来&#xff0c;我国工业领域对于机器视觉技术引导的工业自动化和智能化需求持续上涨&#xff0c;国内机器视觉行业进入快速发展黄金期&#xff0c;但需求广泛出现同时也对机器视觉产品的检测能力提出了更高的要求。 传统机器视觉由人工分析图像特征&am…

JAVA JNA 调用C接口的三种方式

文章目录 1. 准备一个共享库文件2. JNA姿势1—继承Library接口3. JNA姿势2—直接NativeLibrary.getInstance3. JNA姿势3—Native方法 1. 准备一个共享库文件 test.c #include <stdio.h> int test(char *input){printf("input:%s\n",input);return 0; }libtes…

从Matrix-ResourceCanary看内存泄漏监控

作者&#xff1a;小海编码日记 不同于LeakCanary&#xff0c;在Matrix中&#xff0c;主要是通过Resource Canary来监控内存泄漏问题的&#xff0c;且监听的泄漏对象只支持Activity&#xff0c;官方说明如下&#xff1a; 结合分析LeakCanary的经验可知&#xff0c;要实现Activit…

fastadmin iis伪静态应用入口文件index.php

<?xml version"1.0" encoding"UTF-8"?> <configuration><system.webServer><rewrite><rules><rule name"OrgPage" stopProcessing"true"><match url"^(.*)$" /><conditions…

【python知识】用 Tkinter实现“剪刀-石头-布”和“弹球游戏 ”

一、提要 Tkinter是一个Python内置模块&#xff0c;它提供了一个简单易用的界面来创建GUI。 在实现一些动态的画面、如游戏还是需要一些创新性思维的。在本文中&#xff0c;我们将使用 Tkinter 探索 Python GUI 编程。我们将介绍 Tkinter 的基础知识&#xff0c;并演示如何使用…

Element Plus 日期选择器的使用和属性

element plus 日期选择器如果如果没有进行处理 他会返回原有的属性值data格式 如果想要获取选中的日期时间就需要通过以下的代码来实现选中的值 format"YYYY/MM/DD" value-format"YYYY-MM-DD" <el-date-pickerv-model"formInline.date" type&…

「MySQL-05」MySQL Workbench的下载和使用

目录 一、MySQL workbench的下载和安装 1. MySQL workbench介绍 2. 到MySQL官网下载mysql workbench 3. 安装workbench 二、创建能远程登录的用户并授权 1. 创建用户oj_client 2. 创建oj数据库 3. 给用户授权 4. 在Linux上登录用户oj_client检查其是否能操作oj数据库 三、使用…

gerrit 如何提交进行review

前言 本文主要介绍如何使用gerrit进行review。 下述所有流程都是参考&#xff1a; https://gerrit-review.googlesource.com/Documentation/intro-gerrit-walkthrough.html 先给一个commit后但是还没有push上去的一个办法&#xff1a; git reset --hard HEAD^可以多次reset.…

DC/DC开关电源学习笔记(一)开关电源技术概述

&#xff08;一&#xff09;开关电源技术概述 1.什么是开关电源&#xff1f;2.开关电源技术概述2.1 小型化、薄型化、轻量化、高频化2.2 高可靠性2.3 低噪声2.4 采用计算机辅助设计和控制 1.什么是开关电源&#xff1f; 开关模式电源&#xff08;Switch Mode Power Supply&…

opencv的使用(Ubuntu linux环境,AS jni,AS java)

最近要完成一个功能&#xff0c;就是把四个视频合成左右上下分布的一个视频。尝试很多方法&#xff0c;最终使用opencv来实现该功能。&#xff08;通过opencv实现的视频好像没有声音。&#xff09;研究的步骤&#xff0c;首先在Ubuntu环境测试&#xff0c;该功能是否实现。然后…

【Luniux】解决Ubuntu外接显示器不显示的问题

Luniux】解决Ubuntu外接显示器不显示的问题 文章目录 Luniux】解决Ubuntu外接显示器不显示的问题1. 检查nvidia显卡驱动是否正常2. 更新驱动3. 检查显示器是否能检测到Reference 1. 检查nvidia显卡驱动是否正常 使用命令行 nvidia-smi来检查显卡驱动是否正常&#xff0c;如果…

3、监测数据采集物联网应用开发步骤(3)

监测数据采集物联网应用开发步骤(2) 系统整体结构搭建 新建项目 输入项目名称&#xff1a;MonitorData 所谓兵马未动粮草先行&#xff0c;按下图创建好对应的模块备用&#xff1a; com.plugins 业务插件模块 com.zxy.adminlog 日志或文本文…

《C和指针》笔记12: 存储类型(自动变量、静态变量和寄存器变量)

文章目录 1. 自动变量&#xff08;auto&#xff09;1.1 自动变量的初始化 2. 静态变量&#xff08;static&#xff09;2.1 静态变量的初始化 3. 寄存器变量&#xff08;register&#xff09; 1. 自动变量&#xff08;auto&#xff09; 在代码块内部声明的变量的缺省存储类型是…

小白必看:期权行权前必须了解的问题。

期权的本质是一个买权或是卖权&#xff0c;也就是说你是权利方的话&#xff0c;你拥有以约定价格向对手方买入&#xff08;买权&#xff09;或卖出&#xff08;卖权&#xff09;一定数量标的的权利。期权行权就是从对手方买入&#xff0c;或向其卖出标的&#xff01;下文介绍小…