Vue2学习(7) 路由

路由

路由(router)也就是对应关系。

  • SPA

    SPA 指一个 web 网站只有唯一的一个 HTML 页面,所有组件的展示与切换都在这一个页面内完成,也就是单页面应用。

    不同组件之间的切换需要通过前端路由来实现。

  • 前端路由

    概念:Hash 地址与组件之间的对应关系。

    • 工作方式:

      ① 用户点击页面上的路由链接

      ② URL 地址栏中的 Hash 值发生了变化

      ③ 前端路由监听Hash 地址的变化

      ④ 前端路由把当前 Hash 地址对应的组件渲染都浏览器中

    • 实现简易的前端路由:

<!--APP.vue中-->
<template>
  <div class="app-container">
    <h1>App 根组件</h1>

    <a href="#/home">首页</a>
    <a href="#/movie">电影</a>
    <a href="#/about">关于</a>
    <hr />

    <component :is="comName"></component>
  </div>
</template>

<script>
// 创建并导入组件
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'

export default {
  name: 'App',
  data() {
    return
      comName: 'Home'
    }
  },
  created() {
    // App 组件一被创建,立即监听 window 对象的 onhashchange 事件
    //默认像是Home组件,当Hash地址发生变化,页面显示的组件也发生变化
    window.onhashchange = () => {
      switch (location.hash) {
        case '#/home':
          this.comName = 'Home'
          break
        case '#/movie':
          this.comName = 'Movie'
          break
        case '#/about':
          this.comName = 'About'
          break
      }
    }
  },
  // 注册组件
  components: {
    Home,
    Movie,
    About
  }
}
</script>

(简易的前端路由只是用来展示一下工作原理,实际开发中我们不需要这种方式,接下来介绍vue-router)

  • vue-router

    vue-router 是 vue.js 官方给出的路由解决方案,能够轻松管理 SPA 项目中组件的切换(只能结合 vue 项目进行使用)。

  • vue-router的安装和配置步骤

    (1)安装 vue-router 包

    npm i vue-router@3.5.2  -S (@后面接版本)
    

    (2)创建路由模块

    在src目录下,新建router/index.js 路由模块,并初始化:

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    
    // 把 VueRouter 安装为 Vue 项目的插件
    // Vue.use() 函数的作用,就是来安装插件的
    Vue.use(VueRouter)
    
    // 创建路由的实例对象
    const router = new VueRouter({})
    
    
    //向外共享路由实例对象
    export default router
    
    

    (3)导入并挂载路由模块

    在src/main.js入口文件中,导入并挂载路由模块:

    import Vue from 'vue'
    import App from './App.vue'
    
    //导入模块
    import router from '@/router'
    
    new Vue({
      render: h => h(App),
      // 路由挂载
      // router: 路由的实例对象
      router
    }).$mount('#app')
    
    

    (4) 声明路由链接和占位符

    在 src/App.vue 组件中,使用 vue-router 提供的 和 声明路由链接和占位符:

    <template>
      <div class="app-container">
        <h1>App 组件</h1>
    
        <!-- 当安装和配置了 vue-router 后,就可以使用 router-link 来替代普通的 a 链接了 -->
          
        <!-- <a href="#/home">首页</a> -->
        <router-link to="/home">首页</router-link>
        <router-link to="/movie">电影</router-link>
        <router-link to="/about">关于</router-link>
    
        <hr />
    
        <!-- 在项目中安装和配置了 vue-router,就能使用 router-view 这个组件了 -->
        <!-- 定义路由占位符 -->
        <router-view></router-view>
      </div>
    </template>
    

    (5)声明路由的匹配规则(一一对应)

    在 src/router/index.js 路由模块中,通过 routes 数组声明路由的匹配规则(注意这里是routes而不是router)

    // 导入需要的组件
    import Home from '@/components/Home.vue'
    import Movie from '@/components/Movie.vue'
    import About from '@/components/About.vue'
    Vue.use(VueRouter)
    
    // 创建路由的实例对象
    const router = new VueRouter({
      // routes 是一个数组,作用:定义 “hash 地址” 与 “组件” 之间的对应关系
      routes: [
        { path: '/home', component: Home },
       	{ path: '/movie', component: Movie },
        { path: '/about', component: About },
     ]
    })
    
    
    
  • 路由重定向

    用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面。通过路由规则的 redirect 属性,指定一个新的路由地址来设置路由的重定向:

//在 src/router/index.js 路由模块中的 routes 数组添加:
//当用户访问 / 时, 通过redirect 属性跳转到/home对应的路由
	{path: '/', redirect: '/home'}
  • 嵌套路由

    通过路由实现组件的嵌套展示,叫做嵌套路由。

    • 衔接笔记上面的代码举例,在About.vue中创建子路由链接和子路由占位符:

      <template>
        <div class="about-container">
          <h3>About 组件</h3>
      
          <!-- 子级路由链接 -->
      <router-link to="/about/tab1">tab1</router-link>
            
      <router-link to="/about/tab2">tab2</router-link>
            
          <hr />
      
          <!-- 子级路由占位符 -->
          <router-view></router-view>
        </div>
      </template>
      
    • 通过 children 属性声明子路由规则

    //在 src/router/index.js 路由模块中,导入需要的组件,并使用 children 属性声明子路由规则:
    
    //在components中新建tabs文件夹,创建Tab1.vue和Tab2.vue(Tab1和Tab2设置一些文字和背景颜色即可,这里省略)
    
    //导入组件:
    import Tab1 from '@/components/tabs/Tab1.vue'
    import Tab2 from '@/components/tabs/Tab2.vue'
    
    const router = new VueRouter({
     
      routes: [
        {
          path: '/about',
          component: About,
          children: [
            // 子路由规则
            // 默认子路由:如果 children 数组中,某个路由规则的 path 值为空字符串,则这条路由规则,叫做“默认子路由”
            { path: 'tab1', component: Tab1 },
            { path: 'tab2', component: Tab2 }
          ]
        }
      ]
    })
    

    效果如图:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NG5bxn2U-1648701389355)(C:\Users\mi\Desktop\VUE2\子路由01.png)]

    点击tab1:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dw3feK2L-1648701389356)(C:\Users\mi\Desktop\VUE2\子路由02.png)]

    点击tab2:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z8mOS1WU-1648701389357)(C:\Users\mi\Desktop\VUE2\子路由03.png)]

    • 如果希望点击“关于”之后,默认打开tab1组件,可以使用redirect: ‘/about/tab1’ ;也可以使用默认子路由的方式:

      //修改上面代码
      {
            path: '/about',
            component: About,
                
            // redirect: '/about/tab1', 
                
            children: [
       //如果 children 数组中,某个路由规则的 path 值为空字符串,则这条路由规则叫做“默认子路由”
       //同时在About.vue中修改子路由tab1链接路径:<router-link to="/about/">tab1</router-link>
      
              { path: ' ', component: Tab1 },
              { path: 'tab2', component: Tab2 }
            ]
          },
      
  • 动态路由

    • 动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。 在 vue-router 中使用英文的冒号(:)来定义路由的参数项。例如:
    //在src/router/index.js中修改匹配规则:
    //冒号后面也可以用'id'
    { path: '/movie/:mid', component: Movie, props: true },
        
    //修改APP.vue中代码:
    <router-link to="/movie/1">洛基</router-link>
    <router-link to="/movie/2?name=zs&age=20">雷神</router-link>
    <router-link to="/movie/3">复联</router-link>
    
    //这样点击后都能跳转到Movie组件,代替了写多个匹配规则,提高了复用性
    
    • 在动态路由渲染出来的组件中,使用this.$ route.params 对象访问到动态匹配的参数值。在上面的例子中,使用this.$route.params.mid就能查看。

    • 为了简化路由参数的获取形式,vue-router 允许在路由规则中开启 props 传参:

       //src/router/index.js中:
       { path: '/movie/:mid', component: Movie, props: true },
           
       //Movie.vue中:
       export default {
        name: 'Movie',
        // 接收 props 数据,即可获得mid
        props: ['mid'],
      }
      

      补充:

      • 在 hash 地址中, / 后面的参数项,叫做“路径参数”
      • this.$route.params 用来访问路径参数
      • 在 hash 地址中,? 后面的参数项,叫做“查询参数”
      • 在路由“参数对象”中,需要使用 this.$route.query 来访问查询参数
      • 在 this.$route 中,path 只是路径部分;fullPath 是完整的地址
      • 例如:/movie/2?name=zs&age=20 是 fullPath 的值 而/movie/2 是 path 的值
  • 声明式导航 & 编程式导航

    • 通过点击链接实现导航的方式,叫做声明式导航。普通网页中点击 a 链接、vue 项目中点击 都属于声明式导航

    • 调用 API 方法实现导航的方式,叫做编程式导航。例:普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航

    • vue-router 中的编程式导航 API

      最常用的导航 API 分别是:

    (1) this.$router.push(‘hash 地址’)

    ​ 跳转到指定 hash 地址,并增加一条历史记录(网页能够往前和后退历史)

    (2)this.$router.replace(‘hash 地址’)

    ​ 跳转到指定的 hash 地址,并替换掉当前的历史记录(网页不能回到前一个页面)

    (3) this.$router.go(数值 n,正数前进,负数后退)

    ​ 实现导航历史前进、后退;

    ​ 在实际开发中,一般只会前进和后退一层页面,两个便捷方法: $router.back(),在历史记录中,后退到上一个页面; $router.forward(),在历史记录中,前进到下一个页面

  • 全局前置守卫

    • 每次发生路由的导航跳转时,都会触发全局前置守卫。因此,在全局前置守卫中,可以对每个路由进行访问权限的控制:
//在src/router/index.js中:
//to表示将要访问的路由信息对象
//from表示将要离开的路由信息对象
//next是函数,表示放行,允许这次路由导航
router.beforeEach((to,from,next) => {})
  • next 函数的 3 种调用方式:

(图片来自网上)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v5Ibj2to-1648701389357)(C:\Users\mi\Desktop\VUE2\next函数.png)]

当前用户拥有后台主页的访问权限,直接放行:next()

当前用户没有后台主页的访问权限,强制其跳转到登录页面:next(’/login’)

当前用户没有后台主页的访问权限,不允许跳转到后台主页:next(false)

  • 控制后台主页的访问权限
//在src/router/index.js下
//声明全局前置导航守卫
// 只要发生了路由的跳转,必然会触发 beforeEach 指定的 function 回调函数
router.beforeEach(function(to, from, next) {
  // 首先判断是否跳转到/main后台,如果不是直接放行;
  //如果是 /main,则需要登录才能访问,
  //读取 localStorage 中的 token 值,如果有 token,则放行;
  //如果没有 token,则跳转到 /login 登录页
  if (to.path === '/main') {
    //判断是否有 token
    const token = localStorage.getItem('token')
    if (token) {
      next()
    } else {
      next('/login')
    }
  } else {
    next()
  }
})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GDUF-LZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值