vue-Router安装过程及原理详细

编辑: admin 分类: javascript 发布时间: 2021-11-17 来源:互联网
目录
  • 1、前端路由实现原理
  • 2、vue-Router 基本使用
    • 2.1、安装
    • 2.2、配置路由
    • 2.3、实例化
    • 2.4、挂载路由
    • 2.5、页面上添加 router-link 和 router-view
  • 3、router 的模式
    • 3.1、hash 模式
    • 3.2、history 模式
  • 4、router-link的属性
    • 4.1、tag 属性
  • 4.2、replace 属性
    • 4.3、active-class
  • 5、vue-Rrouter 页面跳转方式
    • 5.1、router-link 实现
    • 5.2、通过 js 实现跳转
  • 6、动态路由
    • 7、路由的懒加载
      • 8、嵌套路由
        • 9、router 与 route 区别
          • 10、路由守卫
            • 10.1、全局守卫
            • 10.2、路由独享守卫
            • 10.3、组件内守卫
          • 11、keep-alive
            • 11.1、keep-alive 特定方法
            • 11.2、keep-alive 属性

          后端路由:

          URL 的请求地址与服务器上的资源对应,根据不同的请求地址返回不同的资源。

          前端路由:

          在单页面应用中,根据用户触发的事件,改变URL在不刷新页面的前提下,改变显示内容。

          1、前端路由实现原理

          URL 的 hash 模式

          改变 hash 值的时候,#是一个位置标识符,可以进行页面内的位置跳转,并不会刷新页面。

          通过 location.hash 改变页面的 hash 值,如:

          我们发现页面并不会刷新。

          URL history 模式

          history 模式,有 5 种改变 url 而不刷新页面的方法,分别为:

          • history.pushState() //压入栈
          • history.replaceState() // 替换当前url,不能返回上一个页面
          • history.back() //返回上一个页面
          • history.go(n) //n的值可以是大于0的,表示向前几个,小于0时,表示向后退几个
          • history.forward() //向前一步

          history.go(-1) 等价于 history.back()

          history.go(1) 等价于 history.forward()

          前端三大框架,都有自己的路由:

          Angular ngRouter

          React ReactRouter

          Vue vue-Router

          2、vue-Router 基本使用

          2.1、安装

          npm install vue-router --save
          
          
          

          使用 vue-router 的前提是 vue 必须使用

          在 router 文件夹内 index.js 引入vue-router

          import Vue from 'vue'
          import VueRouter from 'vue-router'
          
          Vue.use(VueRouter) //引用 vue-router 插件
          

          2.2、配置路由

          //配置路由与组件之间的关系
          const route=[
            {
                path: '/',
              // 当访问 '/'的时候 路由重定向 到新的地址 '/home'
              redirect: '/home',
            },
            {
               path: '/home',
               component: home,
             },
             {
               path: '/login',
               component: login,
              },
          ]
           
          
          
          

          2.3、实例化

          const router = new VueRouter({
            mode: "history", //设置模式
            routes
          });
           
          
          

          2.4、挂载路由

          main.js 中,vue 实例化中,把 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">关于</router-link>
          
          <!-- 展示路由内容 -->
          <router-view />
          

          router-link 默认会被渲染成 a 标签,如:

          <router-link to="/home">首页</router-link>
          // 渲染成
          <a href="#/home" rel="external nofollow" >首页</a>
          
          
          

          router-view 是用来占位的,将路由对应的组件展示到该位置。

          3、router 的模式

          路由模式有两种:hash history 模式。

          3.1、hash 模式

          vue-router 默认使用的是 hash 模式。

          hash 的 url 中锚点就是 #xx 号后的内容,通过锚点作为路由地址,我们通常改变的是#号后的内容,实现浏览器渲染指定的组件,锚点发生改变会触发 onhashchange 事件。

          3.2、history 模式

          history就是正常的 url,没有#号,使用的时候需要服务器进行配置。history模式下,对应的方法与上述 5 个方法是一样的。

          vue-router 中可以指定需要的模式:

          const router = new VueRouter({
           mode:'history'
          })
          
          

          4、router-link的属性

          router-link 默认会渲染成 a 标签,但是有时候你想渲染成别的标签也是可以的。

          4.1、tag 属性

          tag属性是用来设置 router-link 标签渲染类型的,如我们想把 router-link 渲染成 button如:

          <router-link to="/home" tag="button">首页</router-link>
          
          
          

          查看渲染后的元素,发现变成 button 标签了,对应的 to 添加的属性值就会失效。此时点击无法跳转到对应内容,可继续阅读下边跳转方式。

          除了 button ,tag 的属性值还可以是其他任意标签,router-link 自动渲染成对应的标签。

          4.2、replace 属性

          replace与上边 history 模式中的 replaceState 对应,跳转的时候不会留下 history 记录,指定replace 的情况下,不能返回上一页。

          <router-link to="/home" replace>首页</router-link>
          
          

          4.3、active-class

          active-class 设置 router-link 点击当前选中的类名,默认情况下类名为:router-link-active

          <a href="#/" rel="external nofollow"  
           aria-current="page" 
           class="router-link-exact-active router-link-active">
           首页
          </a>
          
          
          

          设置当前元素样式需要设置到:router-link-active。

          设置 active-class ,如:

          <router-link to="/" active-class="active">首页</router-link>
          // router-link-active 类名会被替换成 active
          
          
          

          如果需要把全局的 router-link 的选择类名都修改成自定义的,一个一个单独设置工作量太大,可以在 router 中统一设置。

          const router=new VueRouter({
           routes,
           mode: 'hash',
            linkActiveClasss: 'active' //统一设置类名
          })
          
          

          5、vue-Rrouter 页面跳转方式

          5.1、router-link 实现

          // 简单写法
          <router-link to="/">首页</router-link>
          
          //使用动态的path
          <router-link :to="{ path : '/' }"></router-link>
          可以使用path 也可以使用name
          
          //带传参跳转1
          <router-link :to="
          { name:'home', params:{ id:'123' , name:'gq' }}
          ">
          </router-link>
          
          //带传参跳转
          <router-link :to="
          { path:'/', query:{ id:'123' , name:'gq' }}
          ">
          </router-link>
           
          
          

          5.2、通过 js 实现跳转

          // 简单写法
          this.$router.push({ path:'/' })
          // push 与history.pushState 一样
          
          //带参跳转
          this.$router.push({
           name: 'home' , params: { id:'123' , name:'gq' }
          })
          
          //带多种参数
          this.$router.push({
           name: 'home' , 
           params: { id:'123' , name:'gq' },
           query: { plan:'private' }
          })
          
          

          6、动态路由

          在某些情况下,一个页面的 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>
          
           
          //动态设置后边id值
          <router-link :to=" '/user/'+id "> user:{{ id }} </router-link>
          

          获取后边动态值

          this.$route.params.id 
          
          
          

          此处的 id 是配置路由处设置的 id ,只要保持一致就可以了

          方式二:使用 query 进行传参

          <router-link to="/user?id=123"></router-link>
          
          //取值时
          this.$route.query.id
          
          

          另外,this.$router.addRoutes([]) 也可以添加动态路由,里面传的是一个数组,与 routes 配置一样。

          7、路由的懒加载

          懒加载通俗的讲就是使用的时候再加载,不使用的时候不加载。

          打包构建应用程序的时候,js包会变得很大,影响加载速度,如果我们能把不同路由对应的组件分割成不同的代码块,然后访问路由的时候才加载对应的组件,这样就更加高效了。

          路由懒加载到底做了什么呢?主要作用就是将路由对应的组件打包成一个js代码块,只有路由访问的时候,才加载对应的 js 。

          //直接引用的
          import Home from './component/home'
          const routes = [
           {
            path:'/home',
            component:Home
           }
          ]
          
          //懒加载
          const routes = [
           {
            path:'/home',
            component:()=>{ import('./component/home') }
           }
          ]
          

          8、嵌套路由

          实际应用中,通常由多层嵌套的组件组合而成。

          实现步骤:

          第一:创建对应的子组件,并且在路由映射中配置对应的子路由。

          第二:组件内部使用 router-view 标签

          {
           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 组件时,路由为:/body/manager/user

          注意:嵌套路由设置 path 时,不能添加 “/”,否则路由就变了。

          {
           path: "/user",
           component: ()=> import( "../views/manager/user.vue")
          }
          //此时访问路由就变成了 " /user "
           
          
          

          9、router 与 route 区别

          试着在main.js 打印 router 在任意组件内打印 this.$router打印结果如图:

          我们发现两个结果是一模一样的。这样我们就不难理解下面的意思了。

          router VueRouter 实例,拥有自己的方法,如:使用 new VueRouter创建的实例,想要导航到不同url,可以使用 router.push ,跳转方式中有介绍。

          route 为当前活跃状态路由对象,有当前路由的信息,可以通过该对象,获取 pathparams参数、query参数、namematchedhash

          10、路由守卫

          为什么使用导航守卫?我们来考虑一个需求:在 SPA应用中,网页标题跟着页面切换如何变动?

          // 在对应的组件内添加
          created(){
           document.title="测试"
          }
          
          访问该组件时,标题自动切换为 ”测试“
          

          如果使用上述方法,那么对应已开发的组件有多少个,我们就得添加多少次,实在是太麻烦了,所以我们要借助路由守卫,统一修改,也便于维护。

          10.1、全局守卫

          1>、使用 router.beforeEach 注册一个全局前置守卫,只要路由变动时,都会经过它。beforeEach 接收的参数是一个函数,包含的参数有三个。

          router.beforeEach((to,from,next)=>{
          // 路由从 from 跳转到 to 
          // 我们只需要在路由上增加一个 name属性就可以了
           document.title = from.name
           next()
          })
          
          

          注意:上述三个参数顺序不能改变。next 不能丢,必须添加,否则页面跳转的时候没法到下一步,卡在空白区域。

          2>、使用 router.afterEach 注册一个全局后置守卫。

          router.afterEach((to,from)=>{
           console.log('后置守卫')
          })
          
          
          

          这两个守卫都是全局守卫,afterEach 是在路由跳转完成才执行的,所以不需要 next 。参数只有两个。

          10.2、路由独享守卫

          路由配置上直接定义的守卫,用法与全局守卫一致,只是将其放在其中一个路由对象中,只有这个路由下起作用。

          {
           path: "/test",
           name: "测试",
           component: ()=> import( "../views/manager/test.vue"),
           beforeEnter:(to,from,next)=>{
            console.log('test进入前')
            next()
           }
          }
          
          

          这些守卫与全局前置守卫的方法参数是一样的。

          10.3、组件内守卫

          可以在路由组件内直接定义路由导航守卫,定义在组件内的就是组件内守卫。

          const Foo = {
            template: `...`,
            beforeRouteEnter(to, from, next) {
              // 在渲染该组件的对应路由被 confirm 前调用
              // 不!能!获取组件实例 `this`
              // 因为当守卫执行前,组件实例还没被创建
            },
            beforeRouteUpdate(to, from, next) {
              // 在当前路由改变,但是该组件被复用时调用
              // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
              // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
              // 可以访问组件实例 `this`
            },
            beforeRouteLeave(to, from, next) {
              // 导航离开该组件的对应路由时调用
              // 可以访问组件实例 `this`
            }
          }
          
          

           注意:beforeRouteLeave 离开路由时执行,必须添加 next,否则无法正常跳转到下一个路由。

          11、keep-alive

          切换路由的时候页面每次都会重新渲染,我们有的组件会存在一些数据需要保留,不希望来回切换时每次都重新渲染,所以就使用 keep-alive 包裹组件,这样只有第一次执行加载时会执行 created mounted 等钩子函数。

          keep-alive Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

          <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 组件,切换的时候,组件只会在第一次的时候渲染组件,之后进入不会重新渲染。

          11.1、keep-alive 特定方法

          activated(){
           console.log('activated')
          },
          deactivated(){
           console.log("deactivated")
          }
          
          

          这两个函数,只有组件被保持了状态,使用keep-alive时,才是有效会执行的。

          keep-alive生命周期执行顺序:

          created -> mounted -> activated

          deactivated 在退出后才会触发

          11.2、keep-alive 属性

          keep-alive 有两个非常重要的属性:

          include - 字符串或正则表达式,只有匹配组件的时候才会被缓存

          exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存

          <keep-alive include="test">
           <router-view></router-view>
          </keep-alive>
          
          //test组件 添加name属性
          <template>
            <div>
              test
            </div>
          </template>
          <script>
           export default {
            name:'test'
           }
          <script>
          
          

          此时只有 test 组件会被缓存,其他任意组件都不会缓存。

          如果还有其他组件同时需要被缓存,include可添加多个值,只用逗号隔开,但不能添加空格。

          <keep-alive include="test,user">
           <router-view></router-view>
          </keep-alive>
           
          
          

          exclude的使用:

          <keep-alive exclude="test,user">
           <router-view></router-view>
          </keep-alive>
          
          
          

          正好与上实例相反,只有 test,user 两个组件不被缓存,其他的被缓存。

          到此这篇关于 vue-Router安装原理详细过程的文章就介绍到这了,更多相关 vue-Router内容请搜索hwidc以前的文章或继续浏览下面的相关文章希望大家以后多多支持hwidc!