理解vue的use,手写 router vueuse有什么用
ztj100 2024-12-22 22:02 11 浏览 0 评论
前言
先随便聊聊 vue-router 中的一些知识点,一些考点。
- router 初始化以及配置,就不过多赘述,但自己要牢记于心。
- 前几天和大家提到的 路由守卫, 比如router.brforeEach 等一些常用的api。
- 路由懒加载。
{
path: '/about',
component: () => import('./views/About.vue')
}
进行路由匹配的时候,这样使用 import 函数引入,只有匹配到才会进行加载,可以更快的看到首页。所以首页就需要直接在外边 import 关键字导入。
- router-link router-view 。点击 router-link 后,可以跳到其他页面,好像和 a 标签一样。但是它可比 a 强多了,是个组件。router-view 也是个组件,根据相应的路由地址,把对应的组件显示到自己所在的位置。
它们两个是全局组件,但不是 vue 自带的,是需要在 main.js 中 .use 一下才可以使用。这个 .use 到底是怎么回事?今天就来一起看看。
基本准备
1. 项目搭建
<!-- about页面 -->
<template>
<div>
about
</div>
</template>
<!-- home页面 -->
<template>
<div>
home
</div>
</template>
创建页面级别的组件 Home.vue 以及 About.vue,写入这样一个简单的内容。
接着就是基本的创建 router文件夹下的 index.js 来配置这两个组件的路由,About 记得使用懒加载,这里不写出来了。
<template>
<header>
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
</header>
<main>
<router-view></router-view>
</main>
</template>
最后在 App.vue 中用起来就行。
2. 了解 vue 组件
思考 router-link 组件是如何工作的呢?像 router -link 这样不需要引入的组件称为 全局组件 ,注册后可在任何地方直接访问。除了这个还有我们最熟悉的 自定义组件 ,就是我们一般会写在 components 文件夹下的一些组件,需要什么,写一个就行,但是需要显式引入并在组件中注册。最后还有像 transition 这样的内置组件,是 vue 自己提供的。
在 vue 中,使用什么东西来让组件变成为全局组件呢?这是组件的一种声明方式,使用 app.component('router-link', RouterLink)
当我们把 app.use(router) 注释掉后,发现没有了 router-link这个组件了,但是却还是可以看得到 router-link 中的 Home 以及 About 。这又是为什么呢?
当一个组件没有引入,不被支持的时候, dom 会把它当成一般标签来解析。
所以我们要搞明白 .use 到底做了什么?
vue 只负责 组件思想, mvvm 响应式 等核心,其他的交给生态系统,一起开源。vue-router 是vue 生态系统中的路由模块, vue 和它生态的对接,就是这个use方法
手写 router
import { createRouter } from './grouter/index'
现在我们就自己来写 router ,理解 router 。将原来的引入改为 grouter 文件夹下的 idnex ,在这来实现 router 中的 api 。
创建 RouterLink 和 RouterView 这俩个 vue 文件。
1. RouterLink.vue
<!-- RouterLink.vue -->
<template>
<a :href="'#' + $props.to">
<!-- 插槽 -->
<slot />
</a>
</template>
<script setup>
const props = defineProps({
to: {
type: String,
required: true
}
})
</script>
因为 router-link 本来渲染到页面也是 a 标签,所以使用 a 元素来创建一个超链接。href 属性通过 : 简写绑定动态值,它将一个井号 #和 to的值进行拼接,这样创建一个动态的链接。在单页应用中,当用户点击链接时,不会触发页面刷新,而是通过 JavaScript 更改 URL 并显示新的内容。
在子组件模板中,<slot> 标签表示了一个占位符,任何在子组件标签内部定义的内容都将被渲染到这个占位符的位置。这使得父组件可以根据需要自定义链接的显示内容,而无需修改子组件的代码。
2. RouterView.vue
在子组件模板中,<slot> 标签表示了一个占位符,任何在子组件标签内部定义的内容都将被渲染到这个占位符的位置。这使得父组件可以根据需要自定义链接的显示内容,而无需修改子组件的代码。
2. RouterView.vue
xml 代码解读复制代码<!-- RouterView.vue -->
<template>
<component :is="component"></component>
</template>
<script setup>
import { computed } from 'vue'
import { useRouter } from './index.js';
const router = useRouter()
// console.log(router);
// router-view 动态组件 展示 依赖于 url 的变化
const component = computed(() => {
const route = router.routes.find(
(route) => route.path == router.current.value
)
return router? route.component : null
})
</script>
使用 <component> 标签,这是一个特殊的 Vue 标签,允许我们根据传入的 is 属性动态地渲染不同的组件。is 属性会返回当前应该渲染的组件。计算属性根据当前 URL 路径来决定渲染哪个组件。通过查找与当前 URL 路径匹配的路由配置,返回找到的路由配置中指定的组件。
RouterView.vue 负责根据 URL 渲染正确的页面。<a> 链接组件提供了一种简单的方式来创建导航链接。结合这两个组件,我们就可以构建一个基本的手写路由系统,它允许用户通过点击链接来导航到不同的页面,并且页面会根据 URL 路径的变化动态更新。
3. index.js
<!-- index.js -->
import RouterLink from './RouterLink.vue'
import RouterView from './RouterView.vue'
import { ref, inject } from 'vue'
// 单例的责任
export const createRouter = (options) => {
return new Router(options)
}
export const createWebHashHistory = () => {
function bindEvents(fn) {
window.addEventListener('hashchange', fn)
}
// history 对象
return {
url: window.location.hash.slice(1) || '/',
bindEvents
}
}
// 标记一下,router 要向全局暴露
const ROUTER_KEY = '__router__'
// use 开头的是一派 hooks 函数式编程
export const useRouter = () => {
return inject(ROUTER_KEY)
}
class Router {
constructor(options) {
this.history = options.history
this.routes = options.routes
this.current = ref(this.history.url)
this.history.bindEvents(() => {
// console.log('//////////')
this.current.value = window.location.hash.slice(1) || '/'
})
}
// use 调用 插件install
install(app) {
// 全局声明一个router 全局使用的对象
app.provide(ROUTER_KEY, this)
console.log('准备与vue 对接', app)
app.component('router-link', RouterLink)
app.component('router-view', RouterView)
}
}
createWebHashHistory 函数创建一个哈希历史模式的路由历史管理器,它负责监听浏览器的 hashchange 事件并获取当前 URL 的哈希值。
ROUTER_KEY 是一个符号,用于在 Vue 应用程序上下文中标识路由器实例。这在 Vue 组件之间共享路由器实例,以便各个组件可以访问到相同的路由信息和相关的方法。确保整个应用中的所有组件都可以访问同一个路由器实例,而不需要在每个组件中显式传递路由器。
useRouter 函数利用 inject 函数从 Vue 组件的上下文中获取路由器实例。
Router 类是一个构造函数,用于创建路由管理器实例。constructor 方法接收 history 和 routes 作为参数,并初始化路由状态。install 方法用于将路由器实例注入到 Vue 应用程序中,并注册 RouterLink 和 RouterView 组件。
思路巩固
讲了这么些,最后总的来看看 vue-router 到底做了些什么事情。
1. 创建路由组件
RouterLink 负责渲染带有特定 href 的 <a> 标签,其中 href 包含当前路由路径。用户点击时,会改变浏览器 URL 的 hash 部分,触发页面内的导航。
RouterView 负责根据当前 URL 路径动态渲染与之对应的组件。它通过计算属性确定展示哪个组件。
2. 设置路由逻辑
createWebHashHistory 创建一个简单的哈希历史管理器,用于监听 hashchange 事件,并获取当前 URL 的哈希部分作为路由路径。
Router 类 负责管理路由状态,包括当前路径、注册的路由规则等。它还包含一个 install 方法,用于将路由器实例注入到 Vue 应用程序中,并注册全局组件 RouterLink 和 RouterView。
3. 集成到 Vue 应用
使用 createRouter 工厂函数创建路由器实例,并通过 app.use 方法安装到 Vue 应用中。这一步会将路由器实例注册到 Vue 的上下文中,并注册全局组件。
总结
我们首先回顾了一些关于 Vue Router 的基础知识,例如初始化配置、路由守卫、路由懒加载、router-link 和 router-view 的使用等。接着详细介绍了如何手动实现一个简化版的 Vue 路由器。手写一个简易版的 Vue Router 不仅有助于深入理解 Vue Router 的设计原理,还能加深对 Vue 框架的理解。 看完希望对你有帮助,一起加油。
相关推荐
- 从IDEA开始,迈进GO语言之门(idea got)
-
前言笔者在学习GO语言编程的时候,GO语言在国内还没有像JAVA/Php/Python那样普及,绕了不少的弯路,要开始入门学习一门编程语言,最好就先从选择一个好的编程语言的开发环境开始,有了这个开发环...
- 基于SpringBoot+MyBatis的私人影院java网上购票jsp源代码Mysql
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于SpringBoot...
- 基于springboot的个人服装管理系统java网上商城jsp源代码mysql
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于springboot...
- 基于springboot的美食网站Java食品销售jsp源代码Mysql
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于springboot...
- 贸易管理进销存springboot云管货管账分析java jsp源代码mysql
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目描述贸易管理进销存spring...
- SpringBoot+VUE员工信息管理系统Java人员管理jsp源代码Mysql
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍SpringBoot+V...
- 目前见过最牛的一个SpringBoot商城项目(附源码)还有人没用过吗
-
帮粉丝找了一个基于SpringBoot的天猫商城项目,快速部署运行,所用技术:MySQL,Druid,Log4j2,Maven,Echarts,Bootstrap...免费给大家分享出来前台演示...
- SpringBoot+Mysql实现的手机商城附带源码演示导入视频
-
今天为大家带来的是基于SpringBoot+JPA+Thymeleaf框架的手机商城管理系统,商城系统分为前台和后台、前台用的是Bootstrap框架后台用的是SpringBoot+JPA都是现在主...
- 全网首发!马士兵内部共享—1658页《Java面试突击核心讲》
-
又是一年一度的“金九银十”秋招大热门,为助力广大程序员朋友“面试造火箭”,小编今天给大家分享的便是这份马士兵内部的面试神技——1658页《Java面试突击核心讲》!...
- SpringBoot数据库操作的应用(springboot与数据库交互)
-
1.JDBC+HikariDataSource...
- SpringBoot 整合 Flink 实时同步 MySQL
-
1、需求在Flink发布SpringBoot打包的jar包能够实时同步MySQL表,做到原表进行新增、修改、删除的时候目标表都能对应同步。...
- SpringBoot + Mybatis + Shiro + mysql + redis智能平台源码分享
-
后端技术栈基于SpringBoot+Mybatis+Shiro+mysql+redis构建的智慧云智能教育平台基于数据驱动视图的理念封装element-ui,即使没有vue的使...
- Springboot+Mysql舞蹈课程在线预约系统源码附带视频运行教程
-
今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的Springboot+Mysql舞蹈课程在线预约系统,系统项目源代码在【猿来入此】获取!https://www.yuan...
- SpringBoot+Mysql在线众筹系统源码+讲解视频+开发文档(参考论文
-
今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的在线众筹管理系统,主要实现了普通用户在线参与众筹基本操作流程的全部功能,系统分普通用户、超级管理员等角色,除基础脚手架外...
- Docker一键部署 SpringBoot 应用的方法,贼快贼好用
-
这两天发现个Gradle插件,支持一键打包、推送Docker镜像。今天我们来讲讲这个插件,希望对大家有所帮助!GradleDockerPlugin简介...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 从IDEA开始,迈进GO语言之门(idea got)
- 基于SpringBoot+MyBatis的私人影院java网上购票jsp源代码Mysql
- 基于springboot的个人服装管理系统java网上商城jsp源代码mysql
- 基于springboot的美食网站Java食品销售jsp源代码Mysql
- 贸易管理进销存springboot云管货管账分析java jsp源代码mysql
- SpringBoot+VUE员工信息管理系统Java人员管理jsp源代码Mysql
- 目前见过最牛的一个SpringBoot商城项目(附源码)还有人没用过吗
- SpringBoot+Mysql实现的手机商城附带源码演示导入视频
- 全网首发!马士兵内部共享—1658页《Java面试突击核心讲》
- SpringBoot数据库操作的应用(springboot与数据库交互)
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)