• vue-router


    6. vue-router

    1. 理解:一个路由(route)就是一组映射关系(key-value),多个路由需要路由器(router)进行管理
    2. 前端路由:key是路径,value是组件

    6.1 路由基本使用

    安装 vue-router

    npm i vue-router@3
    
    • 1

    引入并使用

    import VueRouter from 'vue-router'
    
    Vue.use(VueRouter)
    
    • 1
    • 2
    • 3

    编写router配置项

    import VueRouter from "vue-router";
    import About from '../components/About.vue';
    import Home from '../components/Home.vue';
    // 创建一个路由器并暴露
    export default new VueRouter({
      routes:[
        {
          path:'/about',
          component:About
        },
        {
          path:'/home',
          component:Home
        }
      ]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    实现切换

    <router-link class="list-group-item" 
                           active-class="active" to="/about">Aboutrouter-link>
    
    • 1
    • 2

    指定展示位置

    <router-view>router-view>
    
    • 1

    App.vue

    <template>
      <div>
        <div class="row">
          <div class="col-xs-offset-2 col-xs-8">
            <div class="page-header"><h2>Vue Router Demo</h2></div>
          </div>
        </div>
        <div class="row">
          <div class="col-xs-2 col-xs-offset-2">
            <div class="list-group">
    					<!-- 原始html中我们使用a标签实现页面的跳转 -->
              <!-- <a class="list-group-item active" href="./about.html">About</a> -->
              <!-- <a class="list-group-item" href="./home.html">Home</a> -->
    
    					<!-- Vue中借助router-link标签实现路由的切换 -->
    					<router-link class="list-group-item" 
                           active-class="active" to="/about">About</router-link>
              <router-link class="list-group-item" 
                           active-class="active" to="/home">Home</router-link>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="panel">
              <div class="panel-body">
    						<!-- 指定组件的呈现位置 -->
                <router-view></router-view>
              </div>
            </div>
          </div>
        </div>
      </div>
    </template>
    <script>
    import AboutVue from './pages/About.vue'
    import HomeVue from './pages/Home.vue'
    
    export default {
        name:'App',
        components:{AboutVue, HomeVue}
    }
    </script>
    
    <style scoped>
      .active {
        background-color: rgb(10, 193, 62);
      }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    main.js

    import Vue from 'vue'
    import App from './App.vue'
    import VueRouter from 'vue-router';
    import router from './router/index';
    Vue.config.productionTip = false
    
    Vue.use(VueRouter)
    
    
    new Vue({
      render: h => h(App),
      router
    }).$mount('#app')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    几个注意点

    1. 路由组件通常存放在 pages 文件夹,一般组件通常存放在 components 文件夹
    2. 通过切换,“隐藏”了的路由组件,默认是被销毁的,需要的时候再去挂载
    3. 每个组件都有自己的 r o u t e route route 属性,里面存储着自己的路由信息
    4. 整个应用只有一个router,可以通过组件的 $router 属性获取到

    6.2 多级路由

    1. 配置路由规则,使用 children 配置项:

      import VueRouter from "vue-router";
      import About from '../pages/About.vue';
      import Home from '../pages/Home.vue';
      import Message from '../pages/Message.vue';
      import News from '../pages/News.vue';
      // 创建一个路由器并暴露
      export default new VueRouter({
        routes:[
          {
            path:'/about',
            component:About,
            children:[
              {
                path:'message',
                component:Message
              },
              {
                path:'news',
                component:News
              }
            ]
          },
          {
            path:'/home',
            component:Home
          }
        ]
      })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      1. 跳转 (要写完整路径)

        <router-link class="list-group-item" 
                               active-class="active" to="/about/message">Messagerouter-link>
        <router-link class="list-group-item" 
                     active-class="active" to="/about/news">Newsrouter-link>
        <router-view>router-view>
        
        • 1
        • 2
        • 3
        • 4
        • 5

    6.3 路由的query参数

    1. 传递参数

      方式一
      <router-link 
       :to="{
            path:'/about/news/detail',
            query:{
            id: m.id,
            title: m.title
            }
            }" 
       active-class="activate"
       >
          {{m.id + ' ' + m.title}}
      router-link>
      方式二
      
      <router-link 
        :to="`/about/message/detail?id=${m.id}&title=${m.title}`" 
        active-class="activate"
      >
        {{m.id + ' ' + m.title}}
      router-link>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
    2. 接收参数

      <h4>{{$route.query.id + ' ' + $route.query.title}}h4>
      
      • 1

    6.4 命名路由

    1. 配置name

      {
        name:'detail',
        path:'detail',
        component:Detail
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
    2. 简化跳转

      <router-link 
       :to="{
            name:'detail',
            query:{
            id: m.id,
            title: m.title
            }
        }" 
       active-class="activate"
       >
          {{m.id + ' ' + m.title}}
      router-link>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

    6.5 路由的params参数

    1. 配置路由,声明接收params参数

      {
        path:'news',
        component:News,
        children:[
          {
            name:'detail',
            path:'detail/:id/:title', // 使用占位符声明接收params参数
            component:Detail
          }
        ]
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    2. 传递参数

      
      <router-link 
        :to="{
          name:'detail',
          params:{
            id: m.id,
            title: m.title
          }
        }" 
        active-class="activate"
      >
        {{m.id + ' ' + m.title}}
      router-link>
      
      
      <router-link 
        :to="`/about/news/detail/${m.id}/${m.title}`" 
        active-class="activate"
      >
        {{m.id + ' ' + m.title}}
      router-link>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
    3. 接收参数

      <h4>{{$route.params.id + ' ' + $route.params.title}}h4>
      
      • 1

    image-20220822113402692

    特别注意:路由携带params参数时若使用to的对象写法,则不能使用path配置项,必须使用name配置

    6.6 路由的props配置

    作用:让路由组件更方便的收到参数

    {
      name:'detail',
      path:'detail', // 使用占位符声明接收params参数
      component:Detail,
      // 第一种写法:props值为对象,该对象所有的key-value组合最终都会通过props传给Detail组件
      // props:{a:7978}
    
      // 第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
      // props:true
    
      // 第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给 Detail组件
      // props(route){
      //   return {
      //     id:route.query.id,
      //     title:route.query.title
      //   }
      // }
      // 简化写法1
      // props({query}){
      //   return {
      //     id:query.id,
      //     title:query.title
      //   }
      // }
      // 简化写法2
      props({query:{id, title}}){
        return {
          id, title
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    6.7 的replace属性

    1. 作用:控制路由跳转时操作浏览器历史记录的模式
    2. 浏览器的历史记录有两种写入方式:分别为pushreplacepush 是追加历史记录,replace 是替换当前记录。路由跳转时候默认为 push
    3. 如何开启 replace 模式:

    6.8 编程式路由导航

    1. 作用:不借助 实现路由跳转,让路由跳转更加灵活

    2. 具体编码

      this.$router.push({
          name:'detail',
          query:{
              id: m.id,
              title: m.title
          }
      })
      
      this.$router.replace({
          name:'detail',
          query:{
              id: m.id,
              title: m.title
          }
      })
      // 前进
      this.$router.forward()
      // 后退
      this.$router.back()
      //跳转指定步数
      this.$router.go(x) // x > 0 前进x步, x < 0 后退x步
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21

    6.9 缓存路由组件

    1. 作用:让不展示的路由组件保持挂载,不被销毁

    2. 具体编码

      <keep-alive include="Message">  include 写组件名
          <router-view>router-view>
      keep-alive>
      
      • 1
      • 2
      • 3

    6.10 两个新的生命周期钩子

    1. 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态
    2. 具体名字:
      1. activated 路由组件激活时触发
      2. deactivated 路由组件失活时触发

    6.11 路由守卫

    1. 作用:对路由进行权限控制

    2. 分类:全局守卫,独享守卫,组件内守卫

    3. 全局守卫:

      // 全局前置守卫:初始化时执行、每次路由切换前执行
      vr.beforeEach((to, from, next)=>{
        if (to.meta.login) {
          if (localStorage.getItem('login') == 'false') {
            console.log(to, from, next);
            alert('请登录')
          } else {
            next()
          }
        } else {
          next()
        }
      })
      //全局后置守卫:初始化时执行、每次路由切换后执行
      vr.afterEach((to, from)=>{
        document.title = to.name
      })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      1. 独享守卫

        beforeEnter(to, from, next){
            if (to.meta.login) {
                if (localStorage.getItem('login') == 'false') {
                    console.log(to, from, next);
                    alert('请登录')
                } else {
                    next()
                }
            } else {
                next()
            }
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
      2. 组件内守卫:

        // 进入守卫:通过路由规则,进入该组件被调用
        beforeRouteEnter(to, from, next) {
            
        }
        // 离开守卫:通过路由规则,离开该组件时被调用
        beforeRouteLeave(to, from, next) {
            
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8

    6.12 路由器的两种工作模式

    1. 对于一个url来说,什么是hash值?————#及其后的内容就是hash值
    2. hash值不会包含在HTTP请求中,即:hash值不会带给服务器
    3. hash模式:
      1. 地址中永远带着#号,不美观
      2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
      3. 兼容性较好
    4. history模式:
      1. 地址干净,美观
      2. 兼容性和hash模式相比较差
      3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题
  • 相关阅读:
    CH9101芯片应用—硬件设计指南
    科软 信息安全 期末考试回忆
    POLARDB IMCI 白皮书 云原生HTAP 数据库系统 一 数据压缩打更新 (本篇有数据到列节点异步但不延迟的解释)...
    【攻防世界-misc】simple_transfer
    你能看到这个汉字么“  ” ?关于Unicode的私人使用区(PUA) 和浏览器端显示处理
    基于 webpack 5 实现自定义 loader
    Unity技术手册-初识编辑器(上)
    AS400-RPG-01
    C语言-指针的进阶
    快手“老”矣,尚能饭否?
  • 原文地址:https://blog.csdn.net/Joker15517/article/details/126474402