Vue前端路由vue-router

路由

  • 对应关系:地址和页面上组件的关系 (Hash地址和组件的关系)
  • SPA单页面应用

拿到当前路由的完整地址location.href
输出:‘http://127.0.0.1:5500/src/test/%E9%94%9A%E9%93%BE%E6%8E%A5.html#b41’
拿到当前路由的hash地址location.hash
‘#b11’

前端路由工作方式

  • 用户点击页面上的路由链接
  • 导致了URL地址栏中的hash值发生了变化
  • 前端路由监听到了hash地址的变化
  • 前端路由把当前地址对应的组件渲染到浏览器中
    在这里插入图片描述

手写简单的路由

  • App.vue根组件使用动态组件
  • 本质就是点击某个连接改变hash地址的值
  • 通过created里面的window.onhashchange来监听hash地址的改变通过location.hash来获取新的hash地址
<template>
	<div>
		<h1>App根组件aa</h1>
		<div>
			<a href="#/home" @click="change('Home')">首页</a>
			<a href="#/movie" @click="change('Movie')">电影</a>
			<a href="#/about" @click="change('About')">关于</a>
		</div>
		<div>
			<component :is="choose"></component>
		</div>
	</div>
</template>

<script>
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'

export default {
  components: {
    Home,
    Movie,
    About
  },
  created () {
    window.onhashchange = () => {
      console.log('监听到hash地址的变化', location.hash)
    }
  },
  data () {
    return {
      choose: 'Home'
    }
  },
  methods: {
    change (val) {
      this.choose = val
      console.log(val)
    }
  }
}
</script>

<style lang="less" scoped>
</style>

在这里插入图片描述

vue-router

如何使用vue-router

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

安装vue-router包
创建路由模块
导入并挂载路由模块
声明路由链接占位符

npm i vue-router@3.5.5 -S
  • /src/router/index.js 创建路由模块
// 导入 Vue和vue-router的包
import Vue from 'vue'
import VueRouter from 'vue-router'

// 调用vue.use函数把 VueRouter 安装为Vue的插件
Vue.use(VueRouter)

// 创建路由的实例对象
const router = new VueRouter()

// 向外共享路由的实例对象
export default router

  • main.js 挂载路由
    在这里插入图片描述

  • 在路由模块下面注册路由规则

// 导入 Vue和vue-router的包
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'

// 调用vue.use函数把 VueRouter 安装为Vue的插件
Vue.use(VueRouter)

// 创建路由的实例对象
const router = new VueRouter({
  // 定义hash地址和组件之间的对应关系的
  routes: [
    // 路由规则
    {
      path: '/home',
      component: Home
    },
    {
      path: '/movie',
      component: Movie
    },
    {
      path: '/about',
      component: About
    }

  ]
})

// 向外共享路由的实例对象
export default router

  • App2.vue使用
  • 使用router-view来进行组件的占位符
  • 连接标签使用router-link来跳转
<template>
	<div>
		<h1>App2根组件</h1>
		<div>
	      <router-link to="/home">首页</router-link>
	      <router-link to="/movie">电影</router-link>
	      <router-link to="/about">关于</router-link>
		</div>
	    <!-- 只要导入了路由模块可以使用router-view组件了 -->
	    <!-- 组件的作用就是占位符 -->
    	<router-view></router-view>
	</div>
</template>

<script>
export default {
  name: 'DemoApp2',
}
</script>

<style lang="less" scoped>
.box{
	display: flex;
}
</style>

路由重定向

  • 用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面。通过路由规则的redirect属性,指定一个新的路由地址,可以很方便的设置路由的重定向
// 创建路由的实例对象
const router = new VueRouter({
  // 定义hash地址和组件之间的对应关系的
  routes: [
    // 路由规则
   	// 重定向
    {
      path: '/',
      redirect: '/home'
    },
    {
      path: '/home',
      component: Home
    },
    {
      path: '/movie',
      component: Movie
    },
    {
      path: '/about',
      component: About
    }

  ]
})

嵌套路由

  • 子组件内嵌套使用
<template>
  <div class="box1">
    <h1>About组件</h1>
    <!-- 子级路由链接 -->
    <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属性声明子路由规则
  • 默认子路由路由重定向都可以实现点击之后优先展示哪个组件

// 创建路由的实例对象
const router = new VueRouter({
  // 定义hash地址和组件之间的对应关系的
  routes: [
     // 子路由规则
    // 默认子路由,如果children数组中,某个路由规则的path值为空字符串,则这条路由规则叫做默认子路由
    {
      path: '/about',
      component: About,
      // redirect: '/about/tab1',
      children: [
        { path: '', component: Tab1 }, // 默认子路由功能和路由重定向一致
        { path: 'tab1', component: Tab1 },
        { path: 'tab2', component: Tab2 }
      ]
    }
  ]
})

动态路由匹配

静态路由的缺点

  • 复用性差 思考一下,如果要写一万条,我们要写一万条路由导向吗?
<div>
  <router-link to="/movie/1">电影1</router-link>
  <router-link to="/movie/2">电影2</router-link>
  <router-link to="/movie/3">电影3</router-link>
</div>
{ path: '/movie/1', component: Movie }
{ path: '/movie/2', component: Movie }
{ path: '/movie/3', component: Movie }

动态参数项

  • 把hash地址中可变的部分定义为参数项,从而提高路由规则的复用性
  • 在vue-router中使用英文的冒号:来定义路由的参数项
{ path: '/movie/:id', component: Movie }
// 在movie组件内希望拿到id来展示对应的值
{
  path: '/movie/:id',
  component: Movie
},
this对象拿到参数

在这里插入图片描述

<template>
  <div class="box3">
    <h1>Movie组件</h1>
    <h3>这是组件传递的值------{{this.$route.params.id}}</h3>
    <button @click="showThis">打印this</button>
  </div>
</template>

为路由规则开始props传参
  • 开启props传参
// 在movie组件内希望拿到id来展示对应的值
    {
      path: '/movie/:id',
      component: Movie,
      props: true
    },
  • 组件内props接收参数
<template>
  <div class="box3">
    <h1>Movie组件</h1>
    <h3>这是组件传递的值------{{id}}</h3>
  </div>
</template>

<script>
export default {
  name: 'Demo3Movie',
  // 接收props参数
  props: ['id'],
</script>

query和fullPath

  • 在hash地址中,/后面的参数项,叫做路径参数
  • 在路由参数对象中,需要使用this.$router.params来访问路径参数
  • 在hash地址中,后面的参数项,叫做查询参数
  • 在路由参数对象中,需要使用this.$router.query来访问路径参数
  • 在路由参数对象中,需要使用this.$router.fullPath来访问完整路由地址
  <router-link to="/movie/1">电影1</router-link>
    <router-link to="/movie/1?name='zs'&age=20">电影1</router-link>

声明式导航&编程式导航

  • 在浏览器中,点击连接实现导航的方式,叫做声明式导航
  • 在浏览器中,调用API方式实现导航的方式,叫做编程式导航

编程式导航

this.$router.push('hash’地址)
  • 跳转到指定的hash地址,并增加一条历史记录
this.$router.replace('hash’地址)
  • 跳转到指定的hash地址,直接替换掉当前的页面
this.$router.go(数值 n)
  • 调用此方法可以在浏览器的历史记录里面前进或者后退
  • 后退层数超出最大层数则不跳转
this.$router.go(-1) // 后退到之前的页面
this.$router.go(1) // 前进到之前的页面
  • 前进和后退一层时的简化写法
this.$router.back() // 后退一层
this.$router.forward() // 前进一层

导航守卫

  • 可以控制路由的访问权限
    在这里插入图片描述
全局前置守卫
  • 在跳转之前就会触发守卫(类似于请求拦截器),在全局前置守卫中,程序员可以对每个路由进行访问权限的控制
const router = new VueRouter({
})
// 为router声明前置导航
// to 表示将要访问的路由信息对象
// from 是将要离开的路由对象信息
// next 是一个函数,调用next() 表示放行,允许这次路由导航
router.beforeEach(function (to, from, next) {
  console.log('要去的路由地址', to)
  console.log('离开的路由地址', from)
  // 表示放行
  /**
   * 当用户拥有权限时直接放行 next()
   * 用户没有权限时,强制其跳转到登陆页面 next('/login')
   * 用户没有权限时,不允许跳转到后台主页 next(false)
   */
  next()
})

在这里插入图片描述

访问拦截
router.beforeEach(function (to, from, next) {
  console.log('要去的路由地址', to)
  console.log('离开的路由地址', from)
  if (to.path === '/main') {
    const token = localStorage.getItem('token')
    if (token) {
      next() // 访问后台有token,直接放行
    } else {
      next('/login') // 访问后台没有token,则跳转到login页面
    }
  } else {
    next() // 访问不是后台主页,直接放行
  }
})
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值