vue-router的原理和實現
阿新 • • 發佈:2021-10-10
vue-router原理
vue-router是實現了前端路由,也就是URL和UI之間的對映關係,當URL改變時會引起UI更新,但無需重新整理頁面。那麼如何實現前端路由呢,也就是如何解決這兩個問題:
- 如何改變URL但是頁面不進行重新整理
- 如何知道URL變化了
然後就引出hash和history兩種實現方式解決上面兩個問題。
hash實現
hash是URL中#後面那一部分,改變URL中的hash部分不會引起頁面重新整理,通過監聽hashchange可以知道URL的變化,改變hashURL的方式有如下幾種:
- 通過瀏覽器前進後退改變URL
- 通過a標籤改變URL
- 通過window.location改變URL
然後監聽hash的變化是hashchange
那麼我們來簡單的實現一下hash去改變URL並且直接更新UI。
<style> .routeView { color: pink; } .routeView2 { color: skyblue; } </style> </head> <body> <ul> <li><a href="#/home">home</a></li> <li><a href="#/cart">cart</a></li> <li><a href="#/user">user</a></li> </ul> <div class="routeView"></div> <div class="routeView2"></div> </body> <script> let routeView = document.querySelector('.routeView') let routeView2 = document.querySelector('.routeView2') //監聽URL的改變 window.addEventListener('hashchange', () => { routeView.innerHTML = location.hash //將URL顯示到routeView中 }) // 監聽UI的重新渲染 window.addEventListener('DOMContentLoaded', () => { if(!location.hash) { location.hash = '/' } else { routeView2.innerHTML = location.hash } }) </script>
然後我們可以發現,當URL改變的時候,UI介面確實發生了更新,但是整個介面並沒有重新渲染。冰狗,完美完成任務。
history實現
history改變URL的方法有如下兩種:
pushState,改變URL後可以記錄之前到過的URL
replaceState,不會記錄之前到過的URL
history監聽URL改變的方法popstate事件,它的特點如下:
- 通過瀏覽器前進後退改變URL時會觸發popstate事件
- 通過pushState/replaceState或a標籤改變URL不會觸發popstate事件
- 可以通過攔截pushState和replaceState的呼叫和a標籤的點選事件來監聽URL的改變
- 通過js呼叫history的back,go,forward方法可以觸發該事件
既然懂了,那就讓我們來完美的實驗一下如何用history完成前端路由:
<!DOCTYPE html>
<html lang="en">
<body>
<ul>
<ul>
<li><a href='/home'>home</a></li>
<li><a href='/about'>about</a></li>
<div id="routeView"></div>
</ul>
</ul>
</body>
<script>
let routerView = routeView
window.addEventListener('DOMContentLoaded', onLoad)
window.addEventListener('popstate', ()=>{
routerView.innerHTML = location.pathname
})
function onLoad () {
routerView.innerHTML = location.pathname
var linkList = document.querySelectorAll('a[href]')
linkList.forEach(el => el.addEventListener('click', function (e) {
e.preventDefault()
history.pushState(null, '', el.getAttribute('href'))
routerView.innerHTML = location.pathname
}))
}
</script>
</html>
(ps:id選擇器可以直接獲取,然後是拿到了window上面
自己實現vue-router
自己做一個vue的外掛,還是很特別的,首先我們知道使用vue-router的話我們是如下這樣簡單使用的:
//index.js中
import vueRouter from 'vue-router'
const routes = [{path: '', component: ''}]
const router = new vueRouter({
mode: 'history',
routes
})
export default router
//main.js中
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.use(router)
new Vue({
render: h => h(App),
router
}).$mount('#app')
因為使用到new去new一個vueRouter,所以可以把它當作一個類,其次用到了Vue.use(),所以必須要有install方法,那我們來寫一個簡單的:
class myRouter() {
}
myRouter.install = function() {}
export default myRouter;
歐克,寫完了,鳴金收兵。hhh,開玩笑的。
然後我們知道vue-router有許多的內建方法,如push,go,replace等等。這些等之後整理好了再來看。