vue3-router

news/2024/11/28 3:54:30/

一、路由

(1)通过 URL 区分路由的机制上,有两种实现方式:

  •  hash 模式:通过 URL 中 # 后面的内容做区分,我们称之为 hash-router;
  •  history 模式:在这种方式下,路由看起来和正常的 URL 完全一致

 (2)这两个不同的原理,在 vue-router 中对应两个函数,分别是 createWebHashHistory createWebHistory

二、实现原理 

 

 (1)hash模式

后来hash 值的变化并不会导致浏览器页面的刷新,只是会触发 hashchange 事件。在代码中,通过对 hashchange 事件的监听,可以在fn 函数内部进行动态地页面切换。

window.addEventListener('hashchange',fn)

(2) history模式

2014 年之后,因为 HTML5 标准发布,浏览器多了两个 API:pushState replaceState。通过这两个 API ,我们可以改变 URL 地址,并且浏览器不会向后端发送请求,同时还会触发 popstate 事件。通过这两个 API 和 popstate 事件,我们就能用另外一种方式实现前端路由

window.addEventListener('popstate', fn)

 三、手写迷你vue-router

(1) 用 Router 类去管理路由。

(2)使用createWebHashHistory 来返回 hash 模式相关的监听代码,以及返回当前 URL 和监听hashchange 事件的方法。

(3)通过 Router 类的 install 方法注册了 Router 的实例,并对外暴露 createRouter 方法去创建 Router 实例。

(4)最后,暴露了useRouter方法,去获取路由实例。

import { ref, inject } from "vue";
import RouterLink from "./RouterLink.vue";
import RouterView from "./RouterView.vue";
const ROUTER_KEY = "__router__";function createRouter(options) {return new Router(options);
}
function userRouter() {return inject(ROUTER_KEY);
}function createWebHashHistory() {function bindEvents(fn) {window.addEventListener("hashchange", fn);}return {bindEvents,url: window.location.hash.slice(1) || "/",};
}class Router {constructor(options) {this.history = options.history;this.routes = options.routes;this.current = ref(this.history.url);this.history.bindEvents(() => {this.current.value = window.location.hash.slice(1);});}install(app) {app.provide(ROUTER_KEY, this);app.component("router-link", RouterLink);app.component("router-view", RouterView);}
}export { createRouter, createWebHashHistory, userRouter };

 (5)使用

import { createRouter, createWebHashHistory } from "./grouter/index";
import About from "../pages/about.vue";
import Count from "../components/Count.vue";
const routes = [{path: "/",name: "Home",component: Count,},{path: "/about",name: "About",component: About,},
];
const router = createRouter({history: createWebHashHistory(),routes,
});

(6)内置组件 router-view

1、在 createRouter 创建的 Router 实例上,current 返回当前的路由地址,并且使用 ref 包裹成响应式的数据。

2、router-view 组件的功能,就是 current 发生变化的时候,去匹配 current 地址对应的组件,然后动态渲染到 router-view 就可以了

3、首先使用 useRouter 获取当前路由的实例;然后通过当前的路由,也就是router.current.value 的值,在用户路由配置 route 中计算出匹配的组件。

4、 最后通过计算属性返回 comp 变量,在 template 内部使用 component 组件动态渲染

<template><component :is="comp"></component>
</template>
<script setup>
import { computed } from "vue";
import { userRouter } from "../grouter/index";let router = userRouter();
const comp = computed(() => {const route = router.routes.find((route) => route.path === router.current.value);return route ? route.component : null;
});
</script>

(7) 内置组件 router-link

 template 渲染一个 a 标签,把 a 标签的 href 属性前面加了个一个 #, 就实现了 hash 的修改。

<template><a :href="'#' + $props.to"><slot></slot></a>
</template>
<script setup>
let props = defineProps({to: { type: String, required: true },
});
</script>

 (8)注册 router-link 和 router-view 这两个组件

import {ref,inject} from 'vue'
import RouterLink from './RouterLink.vue'
import RouterView from './RouterView.vue'
class Router{//....install(app){app.provide(ROUTER_KEY,this)app.component("router-link",RouterLink)app.component("router-view",RouterView)}
}

http://www.ppmy.cn/news/1036956.html

相关文章

form表单的entype属性选取

一、上传文件时entype属性值怎么选取&#xff1f; 上传文件的话必须指定form的enctype&#xff08;encode type&#xff0c;编码类型&#xff09;属性为multipart/form-data&#xff0c;表示表单数据有多部分组成&#xff0c;既有文本又有文件等二进制数据&#xff0c;指定…

UVM学习知识点

UVM构建 include 和 import pkg区别.sv .svhhdl_top.sv和hvl_top.sv回顾uvm_config&#xff0c;以及自定义uvm_configverilog:parameter、defparam与 localparamtest_basebuild_phaseend_of_elaboration_phasefunction void configure_agentset_seqsend_of_elaboration_phaseuv…

java面试题(16):Mysql一致性视图是啥时候建立的

1 演示错误案例 先给大家来一个错误演示。 我们打开两个会话窗口&#xff0c;默认情况下隔离级别是可重复读&#xff0c;我们来看下&#xff1a; 首先在 A 会话中查看当前 user 表&#xff0c;查看完成后开启事务&#xff1a; 可以看到id3的数据sex是男。 接下来在 B 会话中…

uniapp 小兔鲜儿 - 首页模块(2)

目录 热门推荐 首页 – 热门推荐组件 首页 – 获取热门推荐数据 首页 – 热门推荐数据类型并渲染 猜你喜欢 首页 – 猜你喜欢组件 首页 – 获取猜你喜欢数据 首页 – 猜你喜欢数据类型和渲染 首页 – 猜你喜欢分页准备 首页 – 猜你喜欢分页加载 首页 – 猜你喜欢分…

力扣:63. 不同路径 II(Python3)

题目&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从…

周期 角频率 频率 振幅 初相角

周期 角频率 频率 振幅 初相角 当我们谈论傅里叶级数或波形分析时&#xff0c;以下术语经常出现&#xff1a; 周期 T T T: 函数在其图形上重复的时间或空间的长度。周期的倒数是频率。 频率 f f f: 周期的倒数&#xff0c;即一秒内波形重复的次数。单位通常为赫兹&#xff…

各企业的BCI认证该怎么做?

什么是BCI 良好棉花发展协会&#xff08;Better Cotton Initiative&#xff09;简称BCI &#xff0c;是在2009年注册&#xff0c;总部位于瑞士的日内瓦&#xff0c;是一家全球性的非盈利的国际性会员组织机构&#xff0c;是当前世界上最大的可持续棉花种植项目。BCI致力于与…

poi打印

官网&#xff1a;http://deepoove.com/poi-tl 打印 package com.guodi.bpm.form.service.impl;import cn.hutool.core.map.CaseInsensitiveMap; import cn.hutool.core.map.MapUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.converters.date.DateNumbe…