前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >深度解析Vue Router原理:实战指南与实用技巧

深度解析Vue Router原理:实战指南与实用技巧

原创
作者头像
程序视点
发布于 2023-07-31 07:30:52
发布于 2023-07-31 07:30:52
3570
举报
文章被收录于专栏:程序小小事程序小小事

大家好,欢迎来到程序视点!

今天跟大家简单聊聊Router的实现原理,以及我们如何去实现这样一个插件。

Vue RouterVue.js官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。关于Vue Router的使用就不做过多介绍了,大家可以前往Vue Router官网去学习哦~

vue-router插件的基本使用

代码语言:txt
AI代码解释
复制
import Vue from 'vue'  
import Router from 'vue-router'  
Vue.use(Router)  
const router = new Router({routes:[]})  
export default router  
  
import router from './route'  
new Vue({  
    render: h => h(APP),  
    router  
})  

从上述代码可以看出,router也是作为一个插件去使用的,所以在进行原理实践时候,我们开发的就是一个插件。

插件开发思路

定义一个Router类,用来进行所有的router操作。定义一个install方法,将router挂载到Vue的实例上去。注册全局组件router-linkrouter-viewrouter-link组件解析为一个a标签,router-view解析为一个div标签,内容为当前路由对应的component。

监听hashchange事件来改变当前路由对应的component,监听load事件做同样的事情。

对于嵌套路由而言,在渲染router-view时候,先去判断当前router-view的深度,即当前router-view是处在哪个层级,然后在解析routes时候判断当前路由。

如果当前路由和routes中某个路由都为'/'根路由,则直接放到路由渲染数组中,如果当前路由不是根路由,并且routes中的某个路由包含当前路由,则意味着routes数组中的这个路由要么是当前路由的父路由,要么就是当前路由。

然后把routes数组中的这个路由放到路由渲染数组中去,放完之后如果还有childrens,递归去做就行。

最后得到了一个路由匹配数组,这个数组里面包含当前路由和当前路由的父路由,并且数组中子路由的下标与之前router-view的层级下标相等,这样就能正确的将子路由的component正确的渲染到对应的router-view中去了。

譬如当前路由表如下:

代码语言:txt
AI代码解释
复制
routes:[  
    {  
        path: '/',  
        component: () => import ('../views/index.vue')  
    },  
    {  
        path: '/second',  
        component: () => import ('../views/second.vue'),  
        childrens: [  
            {  
                path: '/seconde/article',  
                component: import ('../view/article.vue')  
            }  
        ]  
    }  
]  

此时second组件下有一个router-view,用来渲染子路由——article组件,在app下还有一个父router-view,用来渲染index、second组件,所以此时second组件下的router-view的层级是1(初始化为0)。

如果此时浏览器访问路由 /second/article 时候,触发我们的路由匹配方法,遍历routes数组和当前路由对比,当前路由不是根路由,并且包含 /second 路由,所以path为 /second 的选项被push进入路由渲染数组中,然后此路由还有childrens,进行递归,好家伙,当前路由和 /second/article 完全相等,所以也被push到了渲染数组中。

最后我们得到了一个数组,包含两个路由选项,父路由下标0,子路由下标1,之前我们也将router-view做了层级标记,这样就能得到子router-view对应渲染的component了。~nice

插件开发

先来一个cRouter文件夹,下面搞一个index.js,里面就是我们传统的router使用,上面有,然后再搞一个crouter.js:

代码语言:txt
AI代码解释
复制
import Link from './cLink'  
import View from './cView'  
var Vue  
  
class cRouter {  
  constructor(options) {  
        this.$options = options  
    this.courrentRoute = window.location.hash.slice(1) || '/'  
    //定义一个响应式的路由渲染数组  
        Vue.util.defineReactive(this,'routeMap',[])  
        // 遍历匹配路由  
    this.initRouterMap()  
    // 初始化route改变事件  
    this.initRouteChange()  
  }  
   
  initRouterMap(route) {  
        let routes = route || this.$options.routes  
        for (const routeItem of routes) {  
            if (this.courrentRoute === '/' && routeItem.path === '/') {  
                this.routeMap.push(routeItem)  
                return  
            }  
  
            if (  
            routeItem.path !== '/'  
            &&   
            this.courrentRoute.indexOf(routeItem.path) !== -1) {  
                this.routeMap.push(routeItem)  
                if (routeItem.childrens && routeItem.childrens.length > 0) {  
                    this.initRouterMap(routeItem.childrens)  
                }  
                return  
            }  
        }  
  }  
  
  initRouteChange() {  
    window.addEventListener('hashchange', this.routeChange.bind(this))  
    window.addEventListener('load', this.routeChange.bind(this))  
  }  
  
  routeChange() {  
        this.courrentRoute = window.location.hash.slice(1)  
        this.routeMap = []  
    this.initRouterMap()  
  }  
}  
  
function install(_Vue) {  
  Vue = _Vue  
  
  Vue.mixin({  
    beforeCreate() {  
      if (this.$options.crouter) {  
        Vue.prototype.$crouter = this.$options.crouter  
      }  
    },  
  })  
  
  Vue.component('router-link', Link)  
  
  Vue.component('router-view', View)  
}  
  
export default {  
  cRouter,  
  install,  
}  

cview.js用来渲染router-view

代码语言:txt
AI代码解释
复制
export default {  
    render(h) {  
        // 将自身标记为一个router-view,避免和其他元素搞混  
        this.$vnode.data.routerView = true  
        let parent = this.$parent  
        //默认自己层级为0  
        let routeDeep = 0  
  
        while(parent) {  
            // 判断是否存在父元素并且父元素有值  
            const vodeData = parent.$vnode && parent.$vnode.data  
            if (vodeData) {  
                // 如果父router-view是true,则自身层级增加  
                if (vodeData.routerView) {  
                    routeDeep++  
                }  
            }  
            //继续寻找父元素,进行递归  
            parent = parent.$parent  
        }  
  
        let component = null  
        const route = this.$crouter.routeMap[routeDeep]  
        if (route) {  
            component = route.component  
        }  
        return h(component)  
    }  
}  

cLink.js用来渲染router-link

代码语言:txt
AI代码解释
复制
export default {  
    props: {  
        to: {  
            type: String,  
            default: '/',  
        },  
    },  
    render(h) {  
        return h(  
            'a',  
            { attrs: { href: `#${this.to}` } },  
            this.$slots.default  
        )  
    }  
}  

文章到这里,我们简单实现了类似vue aouter路由的功能~

我想说的是:如今开源框架大大方便了我们的开发效率,但是单纯的使用三方框架并不能让我们学到更多知识我们应该是研究去探索他的实现原理以及设计理念,去思考如果让我们设计一个框架,我们需要掌握哪些知识,该如何设计? 我想,这样的学习才能学到更多的知识~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
vue-router原理分析与实践
Vue Router 是Vue.js官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。关于Vue Router的使用就不做过多介绍了,大家可以前往Vue Router官网去学习哦~
程序员老鱼
2022/12/02
2550
深入分析Vue-Router原理,彻底看穿前端路由
如今大前端的趋势下,你停下学习的脚步了吗?Vue3.0 都 Beta 了,但是还是感觉有些知识点云里雾里的,小编研究了一下Vue-Router源码整理和总结了一些东西,看尤大大怎么设计的。希望能够对你们有所帮助,如果喜欢的话,可以帮忙点个赞。
小丑同学
2020/09/21
2.1K0
如何吃透 vue-router
vue-router 是vue的插件,是对 vue的前端路由管理器,使用中通常分为hash 与 history模式。
前端小tips
2021/11/27
4610
如何吃透 vue-router
Vue-Router 简易实现
# 需求分析 作为一个插件存在:实现VueRouter类和install方法 实现两个全局组件:router-view用于显示匹配组件内容,router-link用于跳转 监控url变化:监听hashchange或popstate事件 响应最新url:创建一个响应式的属性current,当它改变时获取对应组件并显示 # 实现 # 作为一个插件存在 // cvue-router.js let Vue; // 1. 实现一个插件:挂载$router class CVueRouter { constructo
Cellinlab
2023/05/17
2160
跟着来,你也可以手写VueRouter
VueRouter,无疑是每个 Vue 开发者时时刻刻都在使用的东西了,但对于它的源码,你了解多少呢?
isboyjc
2022/03/28
1.6K0
跟着来,你也可以手写VueRouter
手写Vue-router核心原理,再也不怕面试官问我Vue-router原理
在 Web 前端单页应用 SPA(Single Page Application)中,路由描述的是 URL 与 UI 之间的映射关系,这种映射是单向的,即 URL 变化引起 UI 更新(无需刷新页面)。
秋风的笔记
2021/09/22
7.8K1
手写Vue-router核心原理,再也不怕面试官问我Vue-router原理
超燃|从0到1手把手带你实现一款Vue-Router
无论是日常业务还是面试过程中,相信大家对于前端路由这个话题或多或少都有自己的应用和理解。
19组清风
2022/02/28
2.2K0
超燃|从0到1手把手带你实现一款Vue-Router
vue-router路由配置方法
const routes = [ { path: '/home', component: Home }, { path: '/about', component: About } ]
薛定喵君
2020/03/30
9070
手撸vuex和vue-router
把这个store返回出去,那就写完了,核心原理可以说是异常简单。 就用官方文档的案例验证下这个duex有多靠谱:
一粒小麦
2019/07/18
5520
手撸vuex和vue-router
写给vue转react的同志们(6)
众所周知,路由是前端必不可少的一部分,在实际业务中也是我们接触最多的一个模块。那其实不论 Vue 还是 React,他们实现路由的原理都大同小异,既通过 hash 和 history 这两种方式实现。
饼干_
2022/09/19
5660
Vue学习-Vue router
在配置Vue-router时有两种模式,分别为:hash模式(默认)、history模式。
花猪
2022/02/17
4.6K0
Vue学习-Vue router
Vue-router从入门到弃坑
html页面(依次引入vue.js,router.js以及个人配置的app.js)
十月梦想
2018/10/09
2K0
一文详解:Vue3中使用Vue Router
为了便于我们后面代码维护和管理,我们一般将路由相关的代码统一放到一个文件夹中。因此,配置Vue Router的步骤如下:
九仞山
2023/10/14
4K0
手写vue-router核心原理
最近也在观察vue3新特性,抽空玩一玩嵌套路由的vue-router,直接上代码项目目录结构图片代码展示app.vue<template> <div id="app"> <div> <router-link to="/">Index</router-link> | <router-link to="/person">Person</router-link> | <router-link to="/person/info">PersonInfo</router-link>
hellocoder2029
2022/09/26
4320
超详细!Vue-Router手把手教程
最近在重温vue全家桶,再看一遍感觉记忆更深刻,所以专门记录一下(本文vue-router版本为v3.x)。
全栈程序员站长
2022/09/07
2.1K0
vue之vue-router实例
本文转自: https://www.cnblogs.com/SamWeb/p/6610733.html
山行AI
2019/07/30
1.9K0
vue之vue-router实例
Vue之路由(Router)
SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面。
摸鱼的G
2023/02/22
5630
Vue之路由(Router)
Vue router原理
vue-router是vue项目的重要组成部分,用于构建单页应用。单页应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。路由的本质就是建立url和页面之间的映射关系
全栈程序员站长
2022/09/18
5320
vue-router详解——小白速会
一、概述 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。 vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。 而传统的多页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。 路由中有三个基本的概念 route, routes, router。 1. route,它是一条路由,由这个英文单词也可以看出来,它是单数, Home按钮  => home内容
柴小智
2018/04/16
1.7K0
vue-router详解——小白速会
Vue3中的路由功能:安装和配置Vue Router、路由的基本用法、动态路由、嵌套路由
Vue3是一款流行的JavaScript框架,它提供了许多强大的功能来简化前端开发。其中一个重要的特性就是路由管理。在Vue3中,我们可以使用Vue Router库来实现路由功能。本文将详细介绍Vue3中的路由功能,包括安装和配置Vue Router、路由的基本用法、动态路由、嵌套路由等方面。
网络技术联盟站
2023/07/05
10.2K0
相关推荐
vue-router原理分析与实践
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档