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

这篇具有很好参考价值的文章主要介绍了深度解析Vue Router原理:实战指南与实用技巧。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

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

vue-router插件的基本使用

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中去了。

譬如当前路由表如下:

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:

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

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

export default {  
    props: {  
        to: {  
            type: String,  
            default: '/',  
        },  
    },  
    render(h) {  
        return h(  
            'a',  
            { attrs: { href: `#${this.to}` } },  
            this.$slots.default  
        )  
    }  
}  

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

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

到了这里,关于深度解析Vue Router原理:实战指南与实用技巧的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vscode中如何快速生成vue3模板-非常实用的小技巧

    在vue项目开发过程中,我们会发现我们每次新建一个vue组件文件的时候,都需要写一些重复的代码,比如下面代码: 在vscode编辑器中,那有没有什么办法能够让我们快速生成这样的模板呢,答案是有的! 如果觉得对你有帮助的话还望点个赞 + 收藏一下,希望能够帮助到更多

    2024年02月15日
    浏览(61)
  • 【实用技巧】用Vue.js实现智能家居控制系统的前端交互,提高系统的稳定性

    作者:禅与计算机程序设计艺术 【实用技巧】用Vue.js实现智能家居控制系统的前端交互,提高系统的稳定性 1.1. 背景介绍 随着科技的快速发展,智能家居系统越来越受到人们的青睐。智能家居系统不仅能够提高人们的生活质量,还能节约能源、降低家庭开支。然而,智能家

    2024年02月15日
    浏览(68)
  • Elasticsearch权威指南:深度解析搜索技术核心概念、原理及实践

    作者:禅与计算机程序设计艺术 2010年,当时仅仅30岁的Elasticsearch创始人黄文坚就率先发布了开源分布式搜索引擎Elasticsearch。从此, Elasticsearch 名扬天下,成为了当前搜索领域的翘楚。随着 Elasticsearch 的快速崛起,越来越多的人开始关注并应用 Elasticsearch 来进行搜索服务。

    2024年02月10日
    浏览(65)
  • 安全之剑:深度解析 Apache Shiro 框架原理与使用指南

    在现代软件开发中,安全性一直是至关重要的一个方面。随着网络攻击和数据泄露的不断增加,我们迫切需要一种强大而灵活的安全框架来保护我们的应用。Shiro框架就是这样一把利剑,它能够轻松地集成到你的项目中,为你的应用提供可靠的安全性保护。 Apache Shiro是一个强

    2024年04月09日
    浏览(47)
  • 大模型落地实战指南:从选择到训练,深度解析显卡选型、模型训练技、模型选择巧及AI未来展望---打造AI应用新篇章

    早期阶段(1950s~1980s) 在1950年代初期,人们开始尝试使用计算机处理自然语言文本。然而,由于当时的计算机处理能力非常有限,很难处理自然语言中的复杂语法和语义。随着技术的发展,自然语言处理领域在20世纪60年代和70年代取得了一些重要的进展。例如,1970年,美国

    2024年04月09日
    浏览(51)
  • Vue 路由指南:畅游单页应用的地图(Vue Router 和 <router-view>)

    🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入

    2024年02月08日
    浏览(37)
  • Pandas实用技巧

    首先我们需要先提前下载好 示例数据集 : drinksbycountry.csv : http://bit.ly/drinksbycountry imdbratings.csv : http://bit.ly/imdbratings chiporders.csv : http://bit.ly/chiporders smallstockers.csv : http://bit.ly/smallstocks kaggletrain.csv : http://bit.ly/kaggletrain uforeports.csv : http://bit.ly/uforeports 有时你需要知道正在使用的

    2024年02月10日
    浏览(65)
  • Greenplum实用技巧

    gp_segment_id是表中的隐藏列,用来标记该行属于哪个segment节点。因此可以基于该隐藏列进行分组查询,获取每个segment的记录数,从而判断表数据的分布是否均匀或有倾斜。 gp_segment_configuration是一张系统表,它维护包括master、standby在内的所有节点信息。是DBA了解集群最直观的

    2024年02月11日
    浏览(58)
  • chrome-实用技巧

    重发请求,这有一种简单到发指的方式 选中 Network 点击 Fetch/XHR 选择要重新发送的请求 右键选择 Replay XHR  但是经过实际使用调研,发现它只适用于axios或类似方式使用xhr api,则XHR仍在重放,但是,如果使用新的api fetch,则需要使用其他方法,如下:  此方式还可以直接修改

    2024年02月05日
    浏览(57)
  • AI绘画高效实用技巧

    如何调整整体占画面比例的问题 首先看看主要镜头类型: 广角镜头 (10mm至35mm) 拍全身 标准镜头 (35mm至85mm) 半身照 特写镜头 (85mm至300mm) 抓细节 以全画幅135为例: 20mm以下的称之为超广角镜头 21mm~40mm焦距称之为广角镜头 41mm~60mm焦距称之为标准镜头 61mm~100mm焦距称之为中焦镜头

    2024年02月11日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包