Vue3.0 路由学习(八)
2022-07-08 本文已影响0人
coderhzc
一.URL的hash
前端路由是如何做到URL和内容进行映射呢?监听URL的改变。
URL的hash
-- URL的hash也就是锚点(#), 本质上是改变window.location的href属性;
-- 我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新;
-- hash的优势就是兼容性更好,在老版IE中都可以运行,但是缺陷是有一个#,显得不像一个真实的路径。
实际截图
image.png二. HTML5的History
history接口是HTML5新增的, 它有l六种模式改变URL而不刷新页面:
-- replaceState:替换原来的路径;
-- pushState:使用新的路径;
-- popState:路径的回退;
-- go:向前或向后改变路径;
-- forward:向前改变路径;
-- back:向后改变路径;
实际截图
image.png三.认识vue-router
1. vue-router是基于路由和组件的
-- 路由用于设定访问路径, 将路径和组件映射起来.
-- 在vue-router的单页面应用中, 页面的路径的改变就是组件的切换
2. 安装Vue Router:npm install vue-router@4
3. 路由的使用步骤
-- 第一步:创建路由组件的组件;
-- 第二步:配置路由映射: 组件和路径映射关系的routes数组;
-- 第三步:通过createRouter创建路由对象,并且传入routes和history模式;
-- 第四步:使用路由: 通过<router-link>和<router-view>;
三.一路由的基本使用流程
image.pngimage.png
四.一 路由重定向
什么是路由重定向呢? 就是当你打开本地或者线上的项目地址如何路由没有做重定向的话,默认什么也不会在浏览器上显示出来,例如:
image.png
四.二 需求:当打开http://localhost:8081/(本地)或者线上地址的时候我想默认让Home组件的数据显示出来,这种情况的话 就需要使用重定向了redirect
1. 默认情况下, 进入网站的首页, 我们希望<router-view>渲染首页的内容;
2. 但是我们的实现中, 默认没有显示首页组件, 必须让用户点击才可以;
3. 如何可以让路径默认跳到到首页, 并且<router-view>渲染首页组件呢?
-- 我们在routes中又配置了一个映射:
-- (1) path配置的是根路径: /
-- (2) redirect是重定向, 也就是我们将根路径重定向到/home的路径下, 这样就可以得到我们想要的结果了.
4. 具体代码如下:
const routes = [
{
path:'/',
redirect: '/home'
},
{
path:"/home", // 当你点击按钮跳转的路径
component:Home // 当你点击按钮跳转时对应的组件
},
{
path:"/about", // 当你点击按钮跳转的路径
component:About // 当你点击按钮跳转时对应的组件
}
];
实际截图:
image.png五 . 路由的 history模式
const router = createRouter({
history: createWebHistory(process.env.BASE_URL), // 路由的模式指定
routes,
});
image.png
六.router-link
1. router-link事实上有很多属性可以配置:
-- 1.1 to属性: 是一个字符串,或者是一个对象
to属性的实际操作:
image.png -- 1.2 replace属性:设置 replace 属性的话,当点击时,会调用 router.replace(),而不是 router.push();
replace属性实际操作:
image.png -- 1.3 active-class属性:设置激活a元素后应用的class,默认是router-link-active
这个玩意可以做什么用呢?
-- 当需求: 我想让你点击的路由的字体颜色变为红色,你就可以使用这个属性了
active-class属性的实际截图:
image.png -- 1.4 exact-active-class属性:链接精准激活时,应用于渲染的 <a> 的 class,默认是router-link-exact-active;
-- 1.5 tag 属性在Vue3.0中已经被去掉了
实际截图看效果:
image.png七. 路由懒加载
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载:
-- 如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会
更加高效,也可以提高首屏的渲染效率;
-- 其实这里webpack分包知识,而Vue Router默认就支持动态来导入组件:
-- 这是因为component可以传入一个组件,也可以接收一个函数,该函数 需要放回一个Promise;
-- 而import函数就是返回一个Promise;
没有使用 路由懒加载:
image.png使用路由懒加载写法一:
image.png使用路由懒加载写法二:
image.png打包前和打包后的效果
image.png分包命名:
image.png八.路由的其他属性
-- 1. 路由的name属性(name属性的作用:可以通过name属性进行路由跳转):
const routes = [
{
path: "/",
redirect: "/home",
},
{
path: "/home",
component: Home,
name: "home", // name属性的作用:可以通过name属性进行路由跳转
},
{
path: "/about",
component: About,
name: "about", // name属性的作用:可以通过name属性进行路由跳转
}]
以上就是name属性的使用
-- 2. meta属性: 实际代码
const routes = [
{
path: "/",
redirect: "/home",
},
// 懒加载的写法二:
{
path: "/home",
component: Home,
name: "home", // name属性的作用:可以通过name属性进行路由跳转
meta:{
name:'zhangsan',
age: 18
}
},
实际截图
image.png九.动态路由的使用
九.一.在Vue2.0中使用:
image.png九.二.在Vue3.0中使用setup函数中使用:
image.png九.三 匹配多个参数
image.png十.需求: 当我们随便输入一个路径的时候,没有这个路由 让我们显示一个对应的Page Not Found 该咋怎么做了?
image.png十一.如果你想拿到用户输入的乱七八糟的东西的话:
image.png如果在后面多加了一个 星号,它就会自动把路径解析为数组:
image.png十二.嵌套路由(子路由,在子路由中的path:"tab1",在tab1前面千万不要加 / , 不然组件是出不来的):
1.首先分析: 当你在父组件中点击跳转到某一个子组件中,然后子组件下面还有子路由,这种就叫嵌套路由
2.如下是嵌套路由的一个展示图:
image.png3.声明嵌套路由的规则:
image.png4. 嵌套路由的整个代码实现过程如下:
image.png5.子路由重定向redirect
const router = new VueRouter({
// routes是一个数组,作用: 定义"hash地址" 与 "组件"之间的对应关系
routes: [
// {path:'展示的路由地址', component: "要展示的组件"}
// 当用户访问 / 时候,通过 redirect 属性跳转到 /home 对应的路由规则
{ path: "/", redirect: "/home" },
{ path: "/home", component: Home },
{ path: "/move", component: Move },
{
path: "/about",
component: About,
redirect: "/about/tab1", // 这个重定向可以
children: [
// { path: "", redirect: "tab1" }, // 这个重定向也可以
{
path: "tab1", // tab1 前面千万不要加 /
component: Tab1,
},
{
path: "tab2", // tab2 前面千万不要加 /
component: Tab2,
},
],
},
],
});
PS: 这个我在Vue2.0中写过很多次了....不过多记载了
十三. 一 代码实现的页面跳转在Vue2.0中实现跳转-- methods中跳转
image.png十三. 二 代码实现的页面跳转在Vue3.0中实现跳转 setup中跳转
image.pngPS: 同样的在setup中可以使用对象的方式进行跳转
image.png十四.query方式的参数
image.png十五.替换当前的位置
使用push的特点是压入一个新的页面,那么在用户点击返回时,上一个页面还可以回退,但是如果我们希望当前
页面是一个替换操作,那么可以使用replace:
image.png
十六.页面的前进后退
image.png十七. router-link的v-slot
在vue-router3.x的时候,router-link有一个tag属性,可以决定router-link到底渲染成什么元素:
-- 但是在vue-router4.x开始,该属性被移除了;
-- 而给我们提供了更加具有灵活性的v-slot的方式来定制渲染的内容;
1. v-slot如何使用呢?
-- 就是在 router-link 标签中包裹你想要的元素,但是记住:这个地方的所呈现的元素都会被a标签所包裹
实际截图
image.png2. 在router-link中放一个自定组件
实际截图
image.png3. 如果想让router-link 他其实就是一个a标签, 如果不想a标签显示出来的话,就要添加custom
实际截图
image.png4. 其次,我们使用v-slot来作用域插槽来获取内部传给我们的值:
-- href:解析后的 URL(也就是要跳转的路径);
-- route:解析后的规范化的route对象;
-- navigate:触发导航的函数;
-- isActive:是否处于当前页面的活跃状态;
-- isExactActive:是否是精准匹配的状态;
使用作用域 v-slot 实际截图,详细书写:
image.png十八. router-view的v-slot(router-view也提供给我们一个插槽,可以用于 <transition> 和 <keep-alive> 组件来包裹你的路由组件)
十八.一 需求: 现在需要实现整个这个项目中的组件在切换的时候实现动画效果:
image.png十八.二. 需求:这种每次切换的时候都是重新定位的,我想比如说切换到HomeMessage的时候,再去切换其他路由 回来的时候他还在当前页面,这个时候接可以使用keep-alive
image.png十九.动态添加路由 (addRoute)
动态添加路由的业务场景,例如:
1. 某些情况下我们可能需要动态的来添加路由
-- 比如根据用户不同的权限,注册不同的路由;
-- 这个时候我们可以使用一个方法 addRoute;
-- 以下就是动态路由的基本使用
image.png
PS: 这个可以根据具体的业务场景来进行组件的显示和隐藏
2. 要是子路由想使用这种动态路由该怎么办呢?
具体实现如下:
image.png
二十.动态路由的删除
1. 删除路由有以下三种方式:
-- 1.1 方式一:添加一个name相同的路由;
实际截图:
image.png -- 1.2 方式二:通过removeRoute方法,传入路由的名称;
实际截图
image.png -- 1.3 方式三:通过addRoute方法的返回值回调;
实际截图
image.png二十一.路由的补充:
router.hasRoute():检查路由是否存在。
router.getRoutes():获取一个包含所有路由记录的数组。
二十二 路由导航守卫
vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
-- 全局的前置守卫beforeEach是在导航触发时会被回调的:
-- 1.它有两个参数:
-- to:即将进入的路由Route对象;to: 要跳过去的路由对象(例如要跳转到b路由),
-- from:即将离开的路由Route对象;from: 准备从当前要(当前a路由)离开的路由
-- 2. 它有返回值:
-- return false:取消当前导航(也就是说你点击路由跳转,他哪都不去了);当你不希望路由跳转的话,你可以使用return false,这种的话路由就跳转不了了
-- return undefined不返回或者undefined:进行默认导航(就是说他该去哪还是去哪里,这种就叫做默认导航);
实际截图:
image.png -- 3. 返回一个路由地址
-- 可以是一个string类型的路径;
-- 可以是一个对象,对象中包含path、query、params等信息;
-- 4. 可选的第三个参数:next
-- 在Vue2中我们是通过next函数来决定如何进行跳转的;
-- 但是在Vue3中我们是通过返回值来控制的,不再推荐使用next函数,这是因为开发中很容易调用多次next;
实际截图
image.png二十三.其他导航守卫
1. Vue还提供了很多的其他守卫函数,目的都是在某一个时刻给予我们回调,让我们可以更好的控制程序的流程或者功能:
-- https://next.router.vuejs.org/zh/guide/advanced/navigation-guards.html
2. 来看一下完整的导航解析流程: 导航被触发。
-- 在失活的组件里调用 beforeRouteLeave 守卫。
-- 调用全局的 beforeEach 守卫。
-- 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
-- 在路由配置里调用 beforeEnter。
-- 解析异步路由组件。
-- 在被激活的组件里调用 beforeRouteEnter。
-- 调用全局的 beforeResolve 守卫(2.5+)。
-- 导航被确认。
-- 调用全局的 afterEach 钩子。
-- 触发 DOM 更新。
-- 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。