vue2 vue-router源碼解析

目錄

Vue Router 的基本結構和功能

源碼分析

一. 編寫install 方法

二 .生命變量存儲路由信息和當前路由

三 .初始化路由 把路由信息記錄在routeMap中

?四.注冊router-link 和router-view 組件


Vue Router 的基本結構和功能

  1. 路由器實例(Router 實例):Vue Router 提供了一個 VueRouter 類,用于創建路由器實例。路由器實例通常通過 new VueRouter() 創建,并通過 Vue 實例的 router 選項進行注冊。

  2. 路由器插件(Router 插件):Vue Router 提供了一個 install 方法,使其可以作為 Vue.js 插件使用。通過在 Vue 實例上調用 Vue.use(VueRouter),可以在應用程序中全局注冊路由器。

  3. 路由表(Route Table):路由表定義了 URL 和組件之間的映射關系。它是一個包含路由配置的 JavaScript 對象或數組,每個路由配置項都定義了一個 URL 匹配規則和對應的組件。

  4. 路由模式(Router Mode):Vue Router 支持多種路由模式,包括 hash 模式、history 模式和 abstract 模式。這些模式決定了 URL 如何與路由器進行交互。

  5. 路由導航(Route Navigation):Vue Router 提供了一組導航方法,用于在不同的 URL 之間進行導航。它包括 router.push()router.replace()router.go() 等方法,以及 <router-link> 組件用于聲明式的導航。

  6. 導航守衛(Navigation Guards):Vue Router 提供了一組導航守衛,用于在路由導航過程中執行特定的邏輯。導航守衛包括全局前置守衛、路由獨享守衛、組件內的守衛等。

  7. 動態路由和嵌套路由(Dynamic Routing and Nested Routing):Vue Router 支持動態路由和嵌套路由,允許在 URL 中包含動態參數,并且可以在組件中進行嵌套路由的聲明。

  8. 路由狀態管理(Router State Management):Vue Router 允許在路由器實例中定義和管理全局的路由狀態,并通過 $route 對象和 $router 實例提供了訪問和修改路由狀態的方法。

源碼分析

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)

由于在使用Router時 使用了Vue.use 并且Router為一個對象所以 Router里有一個install方法

路由的本質就是地址欄的切換渲染不同的內容

首先我們先新建一個vueRouter文件夾 在這個文件夾下新建一個index.js文件 我們對外暴露一個名字為Router的class 然后在里面寫一個install方法

export default class  Router{static install(){}
}

一. 編寫install 方法

install 方法是默認就加載的我們把初始化邏輯在這里寫

第一步判斷是否注冊過插件 用變量installed來判斷

第二步 把vue構造函數記錄到全局變量

第三步 混入

路由在每個頁面都可以使用 原因就是源碼中使用了混入mixin 在beforeCreate生命周期中在每個組件實例創建之前,將路由配置添加到了組件實例中

let _Vue = null;
export default class Router {static install(Vue) {//判斷是否注冊過插件if (Router.install.installed) {return;}Router.install.installed = true;//把vue構造函數記錄到全局變量_Vue = Vue;//混入_Vue.mixin({beforeCreate() {//這里的this.$options是在Vue 2中,this.$options對象包含了創建Vue實例時傳遞的選項。//當你在Vue實例中使用router選項來配置Vue Router時,它會被保存在this.$options對象中if (this.$options.router) {//把router掛在到_Vue原型上_Vue.prototype.$router = this.$options.router;}},});}
}

二 .生命變量存儲路由信息和當前路由

 constructor(options){//記錄options信息this.options = options//存儲路由信息this.routeMap = {}//記錄當前的路由 默認是/this.data = _Vue.observable({current:'/'})}

三 .初始化路由 把路由信息記錄在routeMap中

 init(){//初始話路由this.createRouteMap(this.options.routes)}//這個方法里涉及到嵌套路由的遍歷createRouteMap(routes){//遍歷所有的路由規則包括嵌套路由 存儲到routeMap中routes.forEach(route=>{// 判斷當前路由是否有path和componentif (route.path && route.component) {// 將path和component作為鍵值對存儲到routeMap中this.routeMap[route.path] = route.component;}// 判斷當前路由是否有子路由if (route.children && route.children.length > 0) {// 遞歸遍歷子路由this.createRouteMap(route.children);}}) }

?四.注冊router-link 和router-view 組件

router-link 的實質就是一個a標簽,我們需要組織默認行為.router-link 跳轉的時候是根據to傳的參數進行的,參數可以是String或者Object類型?我們進行如下寫操作?:

 //注冊組件initCompontent(Vue){Vue.component('router-link',{props:{to:[String,Object]},render(h){return h('a',{attrs:{href:this.resolveTo},on:{click:this.clickHandler},},[this.$slots.default])},computed: {resolveTo() {// 判斷傳入的to是否是對象if (typeof this.to === 'object') {//這里也可以返回path自行判斷return this.to.name} else {// to不是對象,直接使用to作為hrefreturn this.to;}},},methods:{clickHandler(e){//阻止默認事件e.preventDefault()if (typeof this.to === 'object') {for (let key in this.to) {if (this.to.hasOwnProperty(key)) {//這里我默認寫的是name去匹配 實際邏輯要多一點 history.pushState({}, '', this.to.name + this.to[key] );this.$router.data.current = this.to.name;return}}}//利用history.pushState去改變地址欄的路由 無刷新地向當前history插入一條歷使狀態history.pushState({},'',this.to)//渲染新的組件this.$router.data.current = this.to  }}})}

這時候在使用router-link 進行跳轉時是沒有問題的,但是當點擊瀏覽器后退或者前進時,地址欄路徑變了,頁面卻沒有渲染出來

原因就是對應的頁面沒有update,我們還需要監聽瀏覽器的popstate事件

新增方法initEvent 監聽popstate事件,然后從新更新頁面

 initEvent(){window.addEventListener('popstate',()=>{//監聽popstate事件 window.location.pathname獲取路由地址復制給current從新渲染新的頁面this.data.current = window.location.pathname})}

?在init里調用事件

 //初始化init(){this.createRouteMap(this.options.routes)this.initCompontent(_Vue)this.initEvent()}

在initCompontent方法里面注冊router-view組件

 //注冊組件initCompontent(Vue){Vue.component('router-link',{props:{to:[String,Object]},render(h){return h('a',{attrs:{href:this.resolveTo},on:{click:this.clickHandler},},[this.$slots.default])},computed: {resolveTo() {// 判斷傳入的to是否是對象if (typeof this.to === 'object') {return this.to.name} else {// to不是對象,直接使用to作為hrefreturn this.to;}},},methods:{clickHandler(e){//阻止默認事件e.preventDefault()if (typeof this.to === 'object') {for (let key in this.to) {if (this.to.hasOwnProperty(key)) {history.pushState({}, '', this.to.name + this.to[key] );this.$router.data.current = this.to.name;return}}}history.pushState({},'',this.to)this.$router.data.current = this.to  }}})let self = thisVue.component('router-view',{render (h){/這里只是一個簡易版本 當有多個router-view時候會出問題const compontent = self.routeMap[self.data.current]return h(compontent)}})}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/719576.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/719576.shtml
英文地址,請注明出處:http://en.pswp.cn/news/719576.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue.js 修飾符:精準控制組件行為

&#x1f90d; 前端開發工程師、技術日更博主、已過CET6 &#x1f368; 阿珊和她的貓_CSDN博客專家、23年度博客之星前端領域TOP1 &#x1f560; 牛客高級專題作者、打造專欄《前端面試必備》 、《2024面試高頻手撕題》 &#x1f35a; 藍橋云課簽約作者、上架課程《Vue.js 和 E…

多點通信與域套接字:2024/3/4

作業1&#xff1a;廣播 發送端&#xff1a; #include <myhead.h> int main(int argc, const char *argv[]) {//1.創建套接字int sfdsocket(AF_INET,SOCK_DGRAM,0);if(sfd-1){perror("socket error");return -1;}printf("sfd%d\n",sfd);//2.設置當前…

藍橋杯復習之前綴和

題目鏈接&#xff1a;https://www.luogu.com.cn/problem/P8649 思路&#xff1a; 看到區間和&#xff0c;第一反應肯定是前綴和&#xff0c;我們求出前綴和后對前綴和數組每一個值模k&#xff0c;然后對一個數組的值查看前面有幾個相同的&#xff0c;舉個例子&#xff1a;…

【python 常見錯誤】

標題【python 常見錯誤】 一、python 常見錯誤 Python編程過程中&#xff0c;開發者可能會遇到多種類型的錯誤。這些錯誤大致可以分為三類&#xff1a;語法錯誤&#xff08;SyntaxError&#xff09;、邏輯錯誤和運行時錯誤。下面將詳細介紹這幾種錯誤類型&#xff0c;并提供相…

【動態規劃】第十一屆藍橋杯省賽第二場C++ C組《數字三角形》(c++)

1.題目描述 上圖給出了一個數字三角形。 從三角形的頂部到底部有很多條不同的路徑。 對于每條路徑&#xff0c;把路徑上面的數加起來可以得到一個和&#xff0c;你的任務就是找到最大的和。 路徑上的每一步只能從一個數走到下一層和它最近的左邊的那個數或者右邊的那個數。 …

Pytorch學習 day03(Tensorboard)

Tensorboard Tensorboard能夠可視化loss的變化過程&#xff0c;便于我們查看模型的訓練狀態&#xff0c;也能查看模型當前的輸入和輸出結果 在Pycharm中&#xff0c;可以通過按住ctrl&#xff0c;并左鍵點擊某個庫來進入源文件查看該庫的使用方法 SummaryWriter是用來向log_di…

3分鐘,學會一個測試員必懂 Lambda 小知識!

今天再來給大家介紹下函數式接口和方法引用。 函數式接口 問&#xff1a;Lambda 表達式的類型是什么&#xff1f; 答&#xff1a;函數式接口 問&#xff1a;函數式接口是什么&#xff1f; 答&#xff1a;只包含一個抽象方法的接口&#xff0c;稱為函數式接口 &#xff08;…

Linux服務器磁盤及內存用量監控Python腳本(推送釘釘群通知)

文章目錄 Python 腳本釘釘推送通知定時任務 Python 腳本 # -*- coding: utf-8 -*- import subprocessdef get_disk_usage():# 執行 df 命令獲取磁盤使用情況df_process subprocess.Popen([df, -h, /], stdoutsubprocess.PIPE)output, _ df_process.communicate()output out…

Lua 篇(一)— 安裝運行Hello World

目錄 前言一、Lua 是什么&#xff1f;二、Lua和C#的區別三、安裝 LuaLinux 系統上安裝Mac OS X 系統上安裝Window 系統上安裝emmyluaRider 安裝(推薦) 四、Lua學習資料 前言 Lua 是一種輕量級的嵌入式腳本語言&#xff0c;它可以與 C 語言無縫集成&#xff0c;提供了強大的編程…

YOLOv6-Openvino和ONNXRuntime推理【CPU】

1 環境&#xff1a; CPU&#xff1a;i5-12500 Python&#xff1a;3.8.18 2 安裝Openvino和ONNXRuntime 2.1 Openvino簡介 Openvino是由Intel開發的專門用于優化和部署人工智能推理的半開源的工具包&#xff0c;主要用于對深度推理做優化。 Openvino內部集成了Opencv、Tens…

庫函數和頭文件

難道要求平方根也要自己寫一個&#xff1f; #include<iostream> #include<cmath>//頭文件<cmath>中包含許多數學庫函數 using namespace std; int main() {double a;cin>>a;if(a<0) {cout<<"Illegal input"<<endl;return 0;…

PHP語言常見面試題:在PHP中,如何聲明變量?變量的作用域是什么?

在PHP中&#xff0c;聲明變量非常直接和簡單。您只需要在變量名前加上$符號&#xff0c;然后為其分配一個值。這里有一個基本的例子&#xff1a; php復制代碼 <?php $variableName "Hello, World!"; // 聲明一個名為 $variableName 的變量&#xff0c;并賦值為…

DataGrip 2023:讓數據庫開發變得更簡單、更高效 mac/win

JetBrains DataGrip 2023是一款功能強大的數據庫IDE&#xff0c;專為數據庫開發和管理而設計。通過DataGrip&#xff0c;您可以連接到各種關系型數據庫管理系統(RDBMS)&#xff0c;并使用其提供的一組工具來查詢、管理、編輯和開發數據庫。 DataGrip 2023軟件獲取 DataGrip 2…

前端學習第七天-css常用樣式設置

達標要求 掌握元素的顯示與隱藏 熟練應用溢出的文字隱藏 熟練掌握版心和布局流程 1. 元素的顯示與隱藏 在CSS中有三個顯示和隱藏的單詞比較常見&#xff0c;我們要區分開&#xff0c;他們分別是 display visibility 和 overflow。 他們的主要目的是讓一個元素在頁面中消失…

94、利用多線程優化卷積運算

上一節簡單介紹了多線程的概念,同時也介紹了在使用多線程編程時,對于數據在線程間的切分,應該遵循的一個原則:那就是切分獨立的數據快,而不切分有數據依賴的數據塊。 最后還拋出了一個問題:對于卷積算法而言,你覺的切分哪個維度最合適呢? 卷積的切分 之前花了很多篇幅…

數據結構從入門到精通——鏈表

鏈表 前言一、鏈表1.1 鏈表的概念及結構1.2 鏈表的分類1.3 鏈表的實現1.4 鏈表面試題1.5 雙向鏈表的實現 二、順序表和鏈表的區別三、單項鏈表實現具體代碼text.htext.cmain.c單鏈表的打印空間的開辟鏈表的頭插、尾插鏈表的頭刪、尾刪鏈表中元素的查找鏈表在指定位置之前、之后…

LabVIEW齒輪傳動健康狀態靜電在線監測

LabVIEW齒輪傳動健康狀態靜電在線監測 隨著工業自動化的不斷發展&#xff0c;齒輪傳動作為最常見的機械傳動方式之一&#xff0c;在各種機械設備中發揮著至關重要的作用。然而&#xff0c;齒輪在長期運行過程中易受到磨損、變形等因素影響&#xff0c;進而影響整個機械系統的穩…

日常工作總結

日常工作總結 1000. JAVA基礎1. 泛型1.1 泛型和Object的區別 1100. Spring1. 常用注解1.1 ControllerAdvice注解1.2 緩存Cacheable 2. 常用方法2.1 BeanUtils.copyProperties的用法 3. 常用功能組件3.1 過濾器Filter 2000. Linux應用 1000. JAVA基礎 1. 泛型 1.1 泛型和Objec…

【爬蟲實戰】——Python爬取天氣信息

&#x1f349;CSDN小墨&曉末:https://blog.csdn.net/jd1813346972 個人介紹: 研一&#xff5c;統計學&#xff5c;干貨分享 ???????? 擅長Python、Matlab、R等主流編程軟件 ???????? 累計十余項國家級比賽獎項&#xff0c;參與研究經費10w、40w級橫向 文…

大模型推薦落地啦!融合知識圖譜,螞蟻集團發布!

引言&#xff1a;電商推薦系統的新突破 隨著電子商務平臺的蓬勃發展&#xff0c;推薦系統已成為幫助用戶在信息過載時代中篩選和發現產品的關鍵工具。然而&#xff0c;傳統的推薦系統主要依賴歷史數據和用戶反饋&#xff0c;這限制了它們在新商品推出和用戶意圖轉變時的有效性…