vue-Router安裝過程及原理詳細(xì)
后端路由:
URL 的請求地址與服務(wù)器上的資源對應(yīng),根據(jù)不同的請求地址返回不同的資源。
前端路由:
在單頁面應(yīng)用中,根據(jù)用戶觸發(fā)的事件,改變URL在不刷新頁面的前提下,改變顯示內(nèi)容。
1、前端路由實(shí)現(xiàn)原理
URL 的 hash 模式
改變 hash
值的時(shí)候,#是一個位置標(biāo)識符,可以進(jìn)行頁面內(nèi)的位置跳轉(zhuǎn),并不會刷新頁面。
通過 location.hash
改變頁面的 hash 值,如:
我們發(fā)現(xiàn)頁面并不會刷新。
URL
的 history
模式
history
模式,有 5 種改變 url 而不刷新頁面的方法,分別為:
history.pushState()
//壓入棧history.replaceState()
// 替換當(dāng)前url,不能返回上一個頁面history.back()
//返回上一個頁面history.go(n)
//n的值可以是大于0的,表示向前幾個,小于0時(shí),表示向后退幾個history.forward()
//向前一步
history.go(-1)
等價(jià)于 history.back()
history.go(1)
等價(jià)于 history.forward()
前端三大框架,都有自己的路由:
Angular
有 ngRouter
React
有 ReactRouter
Vue
有 vue-Router
2、vue-Router 基本使用
2.1、安裝
npm install vue-router --save
使用 vue-router
的前提是 vue 必須使用
在 router 文件夾內(nèi) index.js 引入vue-router
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) //引用 vue-router 插件
2.2、配置路由
//配置路由與組件之間的關(guān)系 const route=[ { path: '/', // 當(dāng)訪問 '/'的時(shí)候 路由重定向 到新的地址 '/home' redirect: '/home', }, { path: '/home', component: home, }, { path: '/login', component: login, }, ]
2.3、實(shí)例化
const router = new VueRouter({ mode: "history", //設(shè)置模式 routes });
2.4、掛載路由
到 main.js
中,vue 實(shí)例化中,把 router
掛載的 vue 上。
let app = new Vue({ el:'#app', data:{}, // 掛載到vue上面 router, })
2.5、頁面上添加 router-link 和 router-view
<!-- 添加路由 --> <router-link to="/home">首頁</router-link> <router-link to="/about">關(guān)于</router-link> <!-- 展示路由內(nèi)容 --> <router-view />
router-link
默認(rèn)會被渲染成 a 標(biāo)簽,如:
<router-link to="/home">首頁</router-link> // 渲染成 <a href="#/home" rel="external nofollow" >首頁</a>
router-view
是用來占位的,將路由對應(yīng)的組件展示到該位置。
3、router 的模式
路由模式有兩種:hash
和 history
模式。
3.1、hash 模式
vue-router
默認(rèn)使用的是 hash 模式。
hash
的 url 中錨點(diǎn)就是 #xx 號后的內(nèi)容,通過錨點(diǎn)作為路由地址,我們通常改變的是#號后的內(nèi)容,實(shí)現(xiàn)瀏覽器渲染指定的組件,錨點(diǎn)發(fā)生改變會觸發(fā) onhashchange
事件。
3.2、history 模式
history
就是正常的 url,沒有#號,使用的時(shí)候需要服務(wù)器進(jìn)行配置。history模式下,對應(yīng)的方法與上述 5 個方法是一樣的。
vue-router
中可以指定需要的模式:
const router = new VueRouter({ mode:'history' })
4、router-link的屬性
router-link
默認(rèn)會渲染成 a 標(biāo)簽,但是有時(shí)候你想渲染成別的標(biāo)簽也是可以的。
4.1、tag 屬性
tag屬性是用來設(shè)置 router-link 標(biāo)簽渲染類型的,如我們想把 router-link
渲染成 button
,如:
<router-link to="/home" tag="button">首頁</router-link>
查看渲染后的元素,發(fā)現(xiàn)變成 button
標(biāo)簽了,對應(yīng)的 to 添加的屬性值就會失效。此時(shí)點(diǎn)擊無法跳轉(zhuǎn)到對應(yīng)內(nèi)容,可繼續(xù)閱讀下邊跳轉(zhuǎn)方式。
除了 button
,tag 的屬性值還可以是其他任意標(biāo)簽,router-link 自動渲染成對應(yīng)的標(biāo)簽。
4.2、replace 屬性
replace與上邊 history
模式中的 replaceState
對應(yīng),跳轉(zhuǎn)的時(shí)候不會留下 history
記錄,指定replace
的情況下,不能返回上一頁。
<router-link to="/home" replace>首頁</router-link>
4.3、active-class
active-class
設(shè)置 router-link
點(diǎn)擊當(dāng)前選中的類名,默認(rèn)情況下類名為:router-link-active
<a href="#/" rel="external nofollow" aria-current="page" class="router-link-exact-active router-link-active"> 首頁 </a>
設(shè)置當(dāng)前元素樣式需要設(shè)置到:router-link-active。
設(shè)置 active-class ,如:
<router-link to="/" active-class="active">首頁</router-link> // router-link-active 類名會被替換成 active
如果需要把全局的 router-link
的選擇類名都修改成自定義的,一個一個單獨(dú)設(shè)置工作量太大,可以在 router 中統(tǒng)一設(shè)置。
const router=new VueRouter({ routes, mode: 'hash', linkActiveClasss: 'active' //統(tǒng)一設(shè)置類名 })
5、vue-Rrouter 頁面跳轉(zhuǎn)方式
5.1、router-link 實(shí)現(xiàn)
// 簡單寫法 <router-link to="/">首頁</router-link> //使用動態(tài)的path <router-link :to="{ path : '/' }"></router-link> 可以使用path 也可以使用name //帶傳參跳轉(zhuǎn)1 <router-link :to=" { name:'home', params:{ id:'123' , name:'gq' }} "> </router-link> //帶傳參跳轉(zhuǎn) <router-link :to=" { path:'/', query:{ id:'123' , name:'gq' }} "> </router-link>
5.2、通過 js 實(shí)現(xiàn)跳轉(zhuǎn)
// 簡單寫法 this.$router.push({ path:'/' }) // push 與history.pushState 一樣 //帶參跳轉(zhuǎn) this.$router.push({ name: 'home' , params: { id:'123' , name:'gq' } }) //帶多種參數(shù) this.$router.push({ name: 'home' , params: { id:'123' , name:'gq' }, query: { plan:'private' } })
6、動態(tài)路由
在某些情況下,一個頁面的 path
路徑可能是不確定的,如:希望的路徑為 /user/123
或 /user/456
。后邊的值為用戶 id 或其他值。
配置路由
routers:[ { path: '/user/:id', component:()=>{ import('../views/user.vue') } } ]
添加路由
<router-link to="/user/123"> user:123 </router-link> <router-link to="/user/456"> user:456 </router-link> //動態(tài)設(shè)置后邊id值 <router-link :to=" '/user/'+id "> user:{{ id }} </router-link>
獲取后邊動態(tài)值
this.$route.params.id
此處的 id 是配置路由處設(shè)置的 id ,只要保持一致就可以了
方式二:使用 query 進(jìn)行傳參
<router-link to="/user?id=123"></router-link> //取值時(shí) this.$route.query.id
另外,this.$router.addRoutes([])
也可以添加動態(tài)路由,里面?zhèn)鞯氖且粋€數(shù)組,與 routes
配置一樣。
7、路由的懶加載
懶加載通俗的講就是使用的時(shí)候再加載,不使用的時(shí)候不加載。
打包構(gòu)建應(yīng)用程序的時(shí)候,js包會變得很大,影響加載速度,如果我們能把不同路由對應(yīng)的組件分割成不同的代碼塊,然后訪問路由的時(shí)候才加載對應(yīng)的組件,這樣就更加高效了。
路由懶加載到底做了什么呢?主要作用就是將路由對應(yīng)的組件打包成一個js代碼塊,只有路由訪問的時(shí)候,才加載對應(yīng)的 js 。
//直接引用的 import Home from './component/home' const routes = [ { path:'/home', component:Home } ] //懶加載 const routes = [ { path:'/home', component:()=>{ import('./component/home') } } ]
8、嵌套路由
實(shí)際應(yīng)用中,通常由多層嵌套的組件組合而成。
實(shí)現(xiàn)步驟:
第一:創(chuàng)建對應(yīng)的子組件,并且在路由映射中配置對應(yīng)的子路由。
第二:組件內(nèi)部使用 router-view
標(biāo)簽
{ path: "/body", component: ()=> import( "../components/bodyLayout.vue"),, children:[ { path: "manager", component: ()=> import( "../components/blankView.vue"), children:[ { path: "user", component: ()=> import( "../views/manager/user.vue") }, ] }, ] }
訪問 user
組件時(shí),路由為:/body/manager/user
注意:嵌套路由設(shè)置 path 時(shí),不能添加 “/”,否則路由就變了。
{ path: "/user", component: ()=> import( "../views/manager/user.vue") } //此時(shí)訪問路由就變成了 " /user "
9、router 與 route 區(qū)別
試著在main.js
打印 router
在任意組件內(nèi)打印 this.$router
,打印結(jié)果如圖:
我們發(fā)現(xiàn)兩個結(jié)果是一模一樣的。這樣我們就不難理解下面的意思了。
router
為 VueRouter
實(shí)例,擁有自己的方法,如:使用 new VueRouter
創(chuàng)建的實(shí)例,想要導(dǎo)航到不同url,可以使用 router.push
,跳轉(zhuǎn)方式中有介紹。
route 為當(dāng)前活躍狀態(tài)路由對象,有當(dāng)前路由的信息,可以通過該對象,獲取 path
、params
參數(shù)、query
參數(shù)、
、namematched
、hash
10、路由守衛(wèi)
為什么使用導(dǎo)航守衛(wèi)?我們來考慮一個需求:在 SPA應(yīng)用中,網(wǎng)頁標(biāo)題跟著頁面切換如何變動?
// 在對應(yīng)的組件內(nèi)添加 created(){ document.title="測試" } 訪問該組件時(shí),標(biāo)題自動切換為 ”測試“
如果使用上述方法,那么對應(yīng)已開發(fā)的組件有多少個,我們就得添加多少次,實(shí)在是太麻煩了,所以我們要借助路由守衛(wèi),統(tǒng)一修改,也便于維護(hù)。
10.1、全局守衛(wèi)
1>、使用 router.beforeEach
注冊一個全局前置守衛(wèi),只要路由變動時(shí),都會經(jīng)過它。beforeEach 接收的參數(shù)是一個函數(shù),包含的參數(shù)有三個。
router.beforeEach((to,from,next)=>{ // 路由從 from 跳轉(zhuǎn)到 to // 我們只需要在路由上增加一個 name屬性就可以了 document.title = from.name next() })
注意:上述三個參數(shù)順序不能改變。next 不能丟,必須添加,否則頁面跳轉(zhuǎn)的時(shí)候沒法到下一步,卡在空白區(qū)域。
2>、使用 router.afterEach
注冊一個全局后置守衛(wèi)。
router.afterEach((to,from)=>{ console.log('后置守衛(wèi)') })
這兩個守衛(wèi)都是全局守衛(wèi),afterEach
是在路由跳轉(zhuǎn)完成才執(zhí)行的,所以不需要 next
。參數(shù)只有兩個。
10.2、路由獨(dú)享守衛(wèi)
路由配置上直接定義的守衛(wèi),用法與全局守衛(wèi)一致,只是將其放在其中一個路由對象中,只有這個路由下起作用。
{ path: "/test", name: "測試", component: ()=> import( "../views/manager/test.vue"), beforeEnter:(to,from,next)=>{ console.log('test進(jìn)入前') next() } }
這些守衛(wèi)與全局前置守衛(wèi)的方法參數(shù)是一樣的。
10.3、組件內(nèi)守衛(wèi)
可以在路由組件內(nèi)直接定義路由導(dǎo)航守衛(wèi),定義在組件內(nèi)的就是組件內(nèi)守衛(wèi)。
const Foo = { template: `...`, beforeRouteEnter(to, from, next) { // 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用 // 不!能!獲取組件實(shí)例 `this` // 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒被創(chuàng)建 }, beforeRouteUpdate(to, from, next) { // 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用 // 舉例來說,對于一個帶有動態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候, // 由于會渲染同樣的 Foo 組件,因此組件實(shí)例會被復(fù)用。而這個鉤子就會在這個情況下被調(diào)用。 // 可以訪問組件實(shí)例 `this` }, beforeRouteLeave(to, from, next) { // 導(dǎo)航離開該組件的對應(yīng)路由時(shí)調(diào)用 // 可以訪問組件實(shí)例 `this` } }
注意:beforeRouteLeave
離開路由時(shí)執(zhí)行,必須添加 next
,否則無法正常跳轉(zhuǎn)到下一個路由。
11、keep-alive
切換路由的時(shí)候頁面每次都會重新渲染,我們有的組件會存在一些數(shù)據(jù)需要保留,不希望來回切換時(shí)每次都重新渲染,所以就使用 keep-alive
包裹組件,這樣只有第一次執(zhí)行加載時(shí)會執(zhí)行 created mounted
等鉤子函數(shù)。
keep-alive
是 Vue
內(nèi)置的一個組件,可以使被包含的組件保留狀態(tài),或避免重新渲染。
<div id="app"> <router-link to="/home">home</router-link> <router-link to="/login">login</router-link> <keep-alive> <router-view></router-view> </keep-alive> </div>
添加 keep-alive
組件,切換的時(shí)候,組件只會在第一次的時(shí)候渲染組件,之后進(jìn)入不會重新渲染。
11.1、keep-alive 特定方法
activated(){ console.log('activated') }, deactivated(){ console.log("deactivated") }
這兩個函數(shù),只有組件被保持了狀態(tài),使用keep-alive
時(shí),才是有效會執(zhí)行的。
keep-alive生命周期執(zhí)行順序:
created -> mounted -> activated
deactivated
在退出后才會觸發(fā)
11.2、keep-alive 屬性
keep-alive 有兩個非常重要的屬性:
include
- 字符串或正則表達(dá)式,只有匹配組件的時(shí)候才會被緩存
exclude
- 字符串或正則表達(dá)式,任何匹配的組件都不會被緩存
<keep-alive include="test"> <router-view></router-view> </keep-alive> //test組件 添加name屬性 <template> <div> test </div> </template> <script> export default { name:'test' } <script>
此時(shí)只有 test
組件會被緩存,其他任意組件都不會緩存。
如果還有其他組件同時(shí)需要被緩存,include
可添加多個值,只用逗號隔開,但不能添加空格。
<keep-alive include="test,user"> <router-view></router-view> </keep-alive>
exclude的使用:
<keep-alive exclude="test,user"> <router-view></router-view> </keep-alive>
正好與上實(shí)例相反,只有 test
,user
兩個組件不被緩存,其他的被緩存。
到此這篇關(guān)于 vue-Router安裝原理詳細(xì)過程的文章就介紹到這了,更多相關(guān) vue-Router內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue?quill-editor?編輯器使用及自定義toobar示例詳解
這篇文章主要介紹了Vue quill-editor編輯器使用及自定義toobar示例詳解,這里講解編輯器quil-editor的知識結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07一文了解Vue 3 的 generate 是這樣生成 render&n
本文介紹generate階段是如何根據(jù)javascript AST抽象語法樹生成render函數(shù)字符串的,本文中使用的vue版本為3.4.19,感興趣的朋友跟隨小編一起看看吧2024-06-06在vue中根據(jù)光標(biāo)的顯示與消失實(shí)現(xiàn)下拉列表
這篇文章主要介紹了在vue中根據(jù)光標(biāo)的顯示與消失實(shí)現(xiàn)下拉列表,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09在 Vue 應(yīng)用中使用 Netlify 表單功能的方法詳解
Netlify 帶有內(nèi)置表單處理功能,可以用來存儲表單數(shù)據(jù),下載 csv 文件,同時(shí)可以在接收到新的提交時(shí)發(fā)送郵件通知或者通過配置 webhook 發(fā)送請求。這篇文章主要介紹了在 Vue 應(yīng)用中使用 Netlify 表單功能,需要的朋友可以參考下2019-06-06解決Vue使用bus總線時(shí),第一次路由跳轉(zhuǎn)時(shí)數(shù)據(jù)沒成功傳遞問題
這篇文章主要介紹了解決Vue使用bus總線時(shí),第一次路由跳轉(zhuǎn)時(shí)數(shù)據(jù)沒成功傳遞問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07