Vue-router面试可能会问到的(...更新中)

70 阅读3分钟

Vue-router

vue-router是干什么的,为什么用vue-router,为什么不直接用url,权限控制为什么要前端控制

  • 干什么的:单页应用 (SPA) 中将浏览器的 URL 和用户看到的内容绑定起来,当用户在应用中浏览不同页面时,URL 会随之更新,但页面不需要从服务器重新加载(单页面应用的特点) 通过配置路由告诉url路径来显示哪些个组件
  • 为什么用vue-router:spa单页面应用实现url改变页面不刷新,有路由守卫可以实现权限管理,支持两种路由模式(hash、history)、实现管理路由跳转和嵌套等功能
  • 为什么不直接用url:因为用url的话url一改变就会使得整个页面刷新,影响页面性能

vue-router实现核心

  • 添加hashchange事件监听、首先创建一个Router实例,调用addroute给实例维护的一个routes对象添加路径,和回调函数,然后init,给window添加load(页面加载完毕会调用)和hashchange(hash值发生改变)事件监听,添加的事件对url中的hash值进行split并在维护的routes对象中找到对应的key,然后调用该key的对应的函数即可

不用vue-router,用原生js实现路由和路由权限

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>
        <li><a onclick="location . href='#/'">11111</a></li>
        <li><a href="#/admin">22222222</a></li>
        <li><a onclick="location . href='#/server'">333333333</a></li>
    </ul>
    <div id="div">展示</div>
    <script type="text/javascript">
        let res=document . getElementById("div")
        const Router=function(){
            this . route={}
            this . curUrl=''
            this . mode=''
            this . addRoute=(path,cb)=>{
                console . log(path);
                this . route[path]=cb||function(){}
            }
            this . refresh=()=>{
                if(this . mode='history'){
                    this . curUrl=location . pathname
                    this . route[this . curUrl]()
                }else{
                    this . curUrl=location . hash . split('#')[1]||'/'
                    this . route[this . curUrl]()
                }
            }
            this . push=(url)=>{
                history . pushState({},null,url)
                this . refresh()
            }
            this . replace=(url)=>{
                history . replaceState({},null,url)
                this . refresh()
            }
            let res=document . getElementById('div')
            this . init=({mode})=>{
                this . mode=mode
                if(mode=='history'){
                    window . addEventListener("load",this . refresh,false)
                    window . addEventListener("popstate",this . refresh,false)
                }else{
                    window . addEventListener("load",this . refresh,false)
                    window . addEventListener("hashchange",this . refresh,false)
                }
            }
        }
            const router=new Router()
            const baseUrl='/node-template/src/js/easyRoute.html'
            router . addRoute(baseUrl,()=>{
                res . style . backgroundColor='pink'
                res . innerHTML='11111'
            })
            router . addRoute('/node-template/src/js/history.html',()=>{
                res . style . backgroundColor='black'
                res . innerHTML='11111'
            })
        router . init({
            mode:"history"
        })
        router . push('/node-template/src/js/history.html')
    </script>

</body>
</html>

什么是路由守卫,有哪些钩子

就是在进行页面跳转前的一些钩子函数,一般可以用来进行权限判断是否放跳转或者取消

  • beforeEach(全局守卫,每一次路由切换都会执行)
  • beforeEnter (路由独享守卫,在路由中写的用来对特定的路由进行跳转的时候设置的守卫)
  • onBeforeRouteUpdate(路由改变但是当前组件不变时调用) onBeforeRouteLeave(离开时) 组件内的守卫

怎么做权限管理

  • 前端来处理:meta元信息添加该路由的权限信息,在beforeEach中获取用户权限筛选生成路由数组,通过addRoute加入到路由数组和vuex或者pinia中,然后放行。

注意:假如将权限信息直接存放在sessionStorage中,会被代替和修改。

  • 后端处理:直接返回路由数组然后addRoute添加即可

调用不同跳转api分别会触发哪些事件(使用了哪些原生的api)

  • hash模式调用了 绑定在window上的hashchange和load事件
  • history:pushState、replaceState(不会被popState监听)、go、forward、back=>受popState监听(监听历史记录的变化,一旦变化就触发回调函数)
  • 注意:history.go histroy.forward默认也是调用popState方法

vue-router的两种模式,他们的区别

history模式和hash模式

  • 原理:hash模式监听hashchange事件来实现路由和页面的改变,history使用pushState和replaceState仅仅使得state对象从而改变当前 url 地址,不会触发popState,popState只会在go、forward、back等操作才会触发.
  • 表现方式不一样,hash模式有一个hash值,在url中#的后面,可以通过location.hash直接获取到hash值,histroy就是标准的url格式,/xxx/xxx的格式。