「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
- API写法:
-
带参数跳转:
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:如何实现你想要的页面布局
写文不易,如果对你有帮助的话,来一波点赞、收藏、关注吧~👇
相关文章:

「Vue|网页开发|前端开发」02 从单页面到多页面网站:使用路由实现网站多个页面的展示和跳转
本文主要介绍如何使用路由控制来实现将一个单页面网站扩展成多页面网站,包括页面扩展的逻辑,vue的官方路由vue-router的基本用法以及扩展用法 文章目录 本系列前文传送门一、场景说明二、基本的页面扩展页面扩展是在扩什么创建新页面的代码,…...
【Nginx20】Nginx学习:FastCGI模块(二)缓存配置
Nginx学习:FastCGI模块(二)缓存配置 通过上篇文章的学习,普通的 PHP 与 Nginx 的连接就已经没啥大问题了。一般的网站直接那套配置就够了,这也是 Nginx 非常友好的一面。很多在默认的配置文件中注释掉的内容࿰…...

苹果支付外包开发流程
苹果支付的实现流程主要涉及集成苹果的支付系统——Apple Pay,以及在你的应用中处理支付交易。以下是一个简要的实现流程概述,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.开发者账号…...

银河麒麟V10(Tercel)服务器版安装 Docker
一、服务器环境 ## 查看系统版本,确认版本 cat /etc/kylin-release Kylin Linux Advanced Server release V10 (Tercel)## 操作系统 uname -p aarch64## 内核版本(≥ 3.10) uname -r 4.19.90-21.2.ky10.aarch64## iptables 版本(…...

web、HTTP协议
目录 一、Web基础 1.1 HTML概述 1.1.1 HTML的文件结构 1.2 HTML中的部分基本标签 1.3 URI 和 URL 二.HTTP协议 2.1.HTTP概念 2.2.HTTP协议版本 2.3.HTTP请求方法 2.4.HTTP请求访问的完整过程 2.5.HTTP状态码 2.6.HTTP请求报文和响应报文 2.7.HTTP连接优化 三.HTT…...
达梦SQL书写注意事项
模糊查询 模糊查询like后面的字段要求用单引号引用,不能使用双引号 select * from user where name like %小组 分组查询 select查询的列字段必须在分组中的字段存在 正确: select name,age from user group by name,age 错误: select * f…...
博途1200脉冲输出控制速度轴(轴工艺对象基本配置)
这里的1200脉冲轴,主要用来完成线缆包材绕包时的重叠率控制。关于重叠率的具体概念,这里不再阐述,大家可以看下面的文章链接, 重叠率控制 重叠率控制(算法详细介绍含SCL和梯形图源代码)_RXXW_Dor的博客-CSDN博客产品包装和线缆保护材料的包覆都需要进行材料包装重叠率的控…...
微信小程序 通过setData 给两个变量设置同一个数组时,为什么修改一个变量,另一个会也被修改?
在微信小程序中,使用 setData 方法更新数据时,如果给两个变量设置同一个数组,修改其中一个变量的值会导致另一个变量也被修改的原因是,数组是引用类型的数据,在内存中的存储方式是按引用地址存储。 当你将一个数组赋值…...
保障Web安全:构建可靠的网络防御体系
在当今数字化时代,Web安全已成为互联网世界中至关重要的议题。随着网络攻击手段的不断演进和网络犯罪的增加,保护用户数据和确保系统安全性已成为任何Web应用程序的首要任务。本文将深入探讨Web安全的重要性以及构建可靠的网络防御体系的关键要素。我们将…...

LeetCode--HOT100题(44)
目录 题目描述:230. 二叉搜索树中第K小的元素(中等)题目接口解题思路代码 PS: 题目描述:230. 二叉搜索树中第K小的元素(中等) 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你…...
大模型调试debug记录
环境:Linux , cuda 11.7 RuntimeError: Distributed package doesnt have NCCL built in 原因:pytorch安装的是cpu版本,需要安装支持gpu版本的 RuntimeError: Distributed package doesnt have NCCL built in - #3 by bdabykov - distrib…...

对话谷歌首席技术官肖恩,搜索引擎的里程碑,来看看搜索引擎界的大哥Algolia的“快、准、狠”突围关键
原创 | 文 BFT机器人 人物背景 Character Background Sean Mullaney是Algolia(端到端人工智能搜索和发现平台)的首席技术官,也是前 Stripe和谷歌高管,拥有扩展工程组织、开发人工智能驱动的搜索和发现工具以及在全球范围内发展A…...
DP读书:鲲鹏处理器 架构与编程(十二)鲲鹏软件实战案例
10min速通了解鲲鹏软件实战案例 云服务器源码移植与编译配置云服务器Porting Advisor代码移植搭建交叉编译环境x86云服务器交叉编译 OpenSSL鲲鹏云服务器上编译 OpenSSL Docker的安装与应用安装DockerDocker运行与验证Docker常用命令卸载Docker安装适配鲲鹏架构的Docker镜像 KV…...

前端 -- 基础 VSCode 工具生成骨架标签新增代码 解释详解
目录 文档类型声明标签 Lang 语言种类 字符集 文档类型声明标签 <!DOCTYPE> 文档类型声明,作用就是告诉浏览器 当前的页面是 使用哪种 HTML 版本 来显示的网页 HTML 版本也很多呀 ,比如 : HTML5 ,HTML4,XHTML 等…...

爬虫逆向实战(二十三)--某准网数据
一、数据接口分析 主页地址:某准网 1、抓包 通过抓包可以发现数据接口是api_to/search/company_v2.json 2、判断是否有加密参数 请求参数是否加密? 通过查看“载荷”模块可以发现b参数和kiv参数是加密参数 请求头是否加密? 无响应是否加…...
ruoyi--数据权限
这篇文章我先和大家分析一下 RuoYi-Vue 脚手架中 DataScope 注解的实现原理,在 TienChin 项目视频中到时候还会有深入讲解。 1. 思路分析 首先我们先来捋一捋这里的权限实现的思路。 DataScope 注解处理的内容叫做数据权限,就是说你这个用户登录后能够…...
快速开发平台是什么?和传统开发平台相比有哪些区别?
本文可以从【快速开发平台的价值、和传统平台的区别、使用感受】三个方面来说明。 首先,我们要清楚快速开发平台是什么: 快速开发平台也称为低代码或无代码平台,旨在通过可视化工具、拖放式界面和预构建组件,使应用程序的开发过…...
Android基于JNI的Java与C++互调
java调用C++: #include <jni.h> //导出c函数格式 extern "C" JNIEXPORT //供JNI调用 JNICALL 函数名格式 Java_包名_类名_函数名(包名.替换为_) Java_com_example_getapplist_MainActivity_stringFromJNI 包名:com_example_getapplist 类名:MainActi…...

【算法与数据结构】513、LeetCode找树左下角的值
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:这道题用层序遍历来做比较简单,最底层最左边节点就是层序遍历当中最底层元素容器的第一个值…...
React——组件缓存 react-activation
1、安装依赖 npm i -S react-activation 2、包裹根组件 import { AliveScope } from "react-activation"<AliveScope><App /> </AliveScope> 3、缓存组件 import { KeepAlive } from "react-activation"export default () > {co…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...