vue-router的原理和实现

我之前写了一半了,居然又没见了就离谱,从头开始。
5A1htO.md.jpg

vue-router原理

vue-router是实现了前端路由,也就是URL和UI之间的映射关系,当URL改变时会引起UI更新,但无需刷新页面。那么如何实现前端路由呢,也就是如何解决这两个问题:

  1. 如何改变URL但是页面不进行刷新
  2. 如何知道URL变化了
    然后就引出hash和history两种实现方式解决上面两个问题。

hash实现

hash是URL中#后面那一部分,改变URL中的hash部分不会引起页面刷新,通过监听hashchange可以知道URL的变化,改变hashURL的方式有如下几种:

  1. 通过浏览器前进后退改变URL
  2. 通过a标签改变URL
  3. 通过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事件,它的特点如下:

  1. 通过浏览器前进后退改变URL时会触发popstate事件
  2. 通过pushState/replaceState或a标签改变URL不会触发popstate事件
  3. 可以通过拦截pushState和replaceState的调用和a标签的点击事件来监听URL的改变
  4. 通过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等等。这些等之后整理好了再来看。

posted @ 2021-10-10 14:29  卿六  阅读(670)  评论(0编辑  收藏  举报