vue-router的使用

vue-router是vue基础工具的重要组成部分。
通过简单的配置路由组件映射关系,可以实现vue页面轻松跳转。
 
什么是前端路由
它是URL地址与组件之间的对应关系,通常使用Hash地址与组件之间对应。
浏览器的Hash地址就是URL地址中对应的锚链接地址, 如:
location.href: 完整的URL地址。
location.hash: URL地址中,#后面的部分,包括#。
 
锚点链接点击跳转
点击链接box3, 那么页面就滚动到box3对应的部分。
1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
  <div class="nav-bar">
    <a href="#box1">box1</a>
    <a href="#box2">box2</a>
    <a href="#box3">box3</a>
    <a href="#box4">box4</a>
  </div>
 
  <div id="box1"></div>
  <div id="box2"></div>
  <div id="box3"></div>
  <div id="box4"></div>
</body>
前端路由的工作方式
1.点击路由链接a标签
2浏览器URL地址中的hash值发送变化
3.前端路由监听到URL地址中的hash发生变化
4.前端路由拿到hash值对应的组件component, 然后渲染到浏览器对应的位置。
URL的hash地址与组件components的对应关系。

vue-router的实现原理

1.点击链接,切换url的hash地址
1
2
3
4
5
6
7
8
9
10
11
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
 
    <a href="#/home">主页</a>
    <a href="#/center">个人中心</a>
    <a href="#/about">关于</a>
 
    <component :is="comName"></component>
  </div>
</template>

2.监听window.onhashchange浏览器hash地址变化,hash地址变化时,动态修改组件类型

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
<script>
import Home from '@/components/Home/Home.vue'
import Center from './components/Center/Center.vue'
import About from './components/About/About.vue'
 
export default {
  name: 'RouterDemoApp',
  components: {
    Home,
    About,
    Center
  },
 
  created () {
    window.onhashchange = () => {
      switch (location.hash) {
        case '#/home':
          this.comName = 'Home'
          break
        case '#/center':
          this.comName = 'Center'
          break
        case '#/about':
          this.comName = 'About'
          break
      }
    }
  },
 
  data () {
    return {
      comName: 'Home'
    }
  },
}
</script>

vue-router的基本使用

1.在src目录下,创建router目录,然后创建index.js文件,在文件中添加路由配置如下
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
import Vue from 'vue'
import Router from 'vue-router'
import About from '@/components/About/About.vue'
import Center from '@/components/Center/Center.vue'
import Home from '@/components/Home/Home.vue'
 
// 将Router安装为Vue的插件
//Vue全局引入插件vue-router
//Vue在调用vue-router的install方法时,会引入2个全局组件router-link, router-view
//router-link: 和<a>的作用一样,用于href调整链接
//router-view: 代表要跳转的页面的展示位置
Vue.use(Router)
 
// 创建路由的实例对象
//实例属性.$route和$.router的区别
//$router: 拥有路由的所有方法, $route: 拥有路由的所有属性
const router = new Router({
  mode: 'hash', //默认采用hash模式
  routes: [
    { path: '/home', component: Home },
    { path: '/about', component: About },
    { path: '/center', component: Center }
  ]
})
 
export default router

2.在App.vue中,添加路由跳转入口和组件出口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
 
    <!-- <a href="#/home">主页</a>
    <a href="#/center">个人中心</a>
    <a href="#/about">关于</a> -->
 
    <!-- 在vue-router中,使用router-link代替a标签,并且里面的to属性表示要跳转的路由地址 -->
    <router-link to="/home">主页</router-link>
    <router-link to="/center">个人中心</router-link>
    <router-link to="/about">关于</router-link>
 
    <!-- <component :is="comName"></component> -->
    <!-- 使用vue-router默认就存在这个占位组件,这个是路由视图的出口 -->
    <router-view></router-view>
  </div>
</template>

3.在main.js中,添加路由实例挂载

1
2
3
4
5
6
7
8
9
10
11
import Vue from 'vue'
import App from './App.vue'
import routerObj from '@/router/index'
 
Vue.config.productionTip = false
 
new Vue({
  render: h => h(App),
  // 路由实例挂载
  router: routerObj
}).$mount('#app')

vue-router嵌套路由

如果当前组件下有根据路由展示的子组件,可以在当前路由匹配规则中添加children项,然后在对应数组中添加子路由的路由规则配置。
如果要展示一个默认子路由,可以将这个子路由配置的path设置为""空字符串。
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
import Vue from 'vue'
import Router from 'vue-router'
import About from '@/components/About/About.vue'
import Center from '@/components/Center/Center.vue'
import Home from '@/components/Home/Home.vue'
import Tab1 from '@/components/Tabs/Tab1.vue'
import Tab2 from '@/components/Tabs/Tab2.vue'
 
// 将Router安装为Vue的插件
Vue.use(Router)
 
// 创建路由的实例对象
const router = new Router({
 
  routes: [
    // 地址重定向,当跳转的URL地址没有对应组件时,那么就会强制跳转到另一个地址
    // 重定向:确定原来地址url是啥,看着不爽,要重定向到哪个url
    { path: '/', redirect: '/home' },
    // 路由匹配规则,实例对应是根据匹配规则,从上到下逐条匹配的
    { path: '/home', component: Home },
    // 嵌套路由,就是在对应路由容器配置项上增加children属性, 然后在这个子路由配置上增加嵌套子路由的配置。
    // 嵌套子路由的path配置无需是/开头,默认router会自动添加
    {
      path: '/about',
      component: About,
      // 默认子路由方法1:设置父路由的重定向地址
      // redirect: '/about/tab1',
      children: [
        // { path: 'tab1', component: Tab1 },
        // 默认子路由方法2:在父路由的children中,设置默认路由的path:'', 这样表示父路由默认展示这个子路由
        { path: '', component: Tab1 },
        { path: 'tab2', component: Tab2 }
      ]
    },
    { path: '/center', component: Center }
  ]
})
 
export default router

vue-router动态路由

当一类子路由会随业务不同而动态变化时,那么可以将这个路由的变化部分定义成参数
{ path: 'movie/:id', component: Movie }
添加 props: true选项时,组件内可以通过props参数接收动态路由的路由参数。
{ path: 'movie/:mid', component: Movie, props: true }
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
import Vue from 'vue'
import Router from 'vue-router'
import About from '@/components/About/About.vue'
import Center from '@/components/Center/Center.vue'
import Home from '@/components/Home/Home.vue'
import Tab1 from '@/components/Tabs/Tab1.vue'
import Tab2 from '@/components/Tabs/Tab2.vue'
import Movie from '@/components/Movie/Movie.vue'
 
// 将Router安装为Vue的插件
Vue.use(Router)
 
// 创建路由的实例对象
const router = new Router({
 
  routes: [
    // 地址重定向,当跳转的URL地址没有对应组件时,那么就会强制跳转到另一个地址
    { path: '/', redirect: '/home' },
    // 路由匹配规则,实例对应是根据匹配规则,从上到下逐条匹配的
    { path: '/home', component: Home },
    // 嵌套路由,就是在对应路由容器配置项上增加children属性, 然后在这个子路由配置上增加嵌套子路由的配置。
    // 嵌套子路由的path配置无需是/开头,默认router会自动添加
    {
      path: '/about',
      component: About,
      // 默认子路由方法1:设置父路由的重定向地址
      // redirect: '/about/tab1',
      children: [
        // { path: 'tab1', component: Tab1 },
        // 默认子路由方法2:在父路由的children中,设置默认路由的path:'', 这样表示父路由默认展示这个子路由
        { path: '', component: Tab1 },
        { path: 'tab2', component: Tab2 }
      ]
    },
    {
      path: '/center',
      component: Center,
      children: [
        // id部分是可变路由的参数部分,它是随参数变化的。
        // { path: 'movie/:mid', component: Movie }
        { path: 'movie/:mid', component: Movie, props: true }
      ]
    }
  ]
})
 
export default router

使用时,根据业务不同动态变化路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
  <div class="center-container">
    Center组件
    <hr>
    <!-- 动态路由,将路由地址中随业务动态变化的部分声明成参数类型,如果:movie/:id, id是可变的参数 -->
    <router-link to="/center/movie/1">三国演义</router-link>
    <router-link to="/center/movie/2">红楼梦</router-link>
    <router-link to="/center/movie/3">西游记</router-link>
    <router-link to="/center/movie/4">水浒传</router-link>
    <hr>
 
    <router-view></router-view>
  </div>
</template>

vue-router动态路由参数传递

路由/参数传递
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vue代码如下:
 
<router-link to="/user/detail/1">用户1</router-link>
-----
 
routes代码如下:
 
{  
    // 路径里面传递参数是通过斜线传递的:比如/user/detail/1
    path: 'detail/:id',
    name: 'userDetail',
    component: () => import('../view/UserDetail.vue')
}
----
 
这种参数在组件里面如何获取呢?
 
this.$route.params.id

路径?参数传递

1
2
3
4
5
<router-link to="/user/detail?id=1">用户1</router-link>
 
这种传递方式如何在组件里面获取参数呢?
 
this.$route.query.id

声明式导航与编程式导航

声明式导航:通过在html中写a标签,在vue中写<router-link>标签的方式,实现的跳转叫做声明式导航。
编程式导航:通过调用API的方式实现的跳转,如location.href的方式,叫做编程式导航。
 
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
48
49
50
51
52
53
54
55
<template>
  <div class="home-container">
    Home组件-编程式导航
 
    <hr>
    <button @click="handlePush">push:调用</button>
    <button @click="handleReplace">replace:调用</button>
    <button @click="handleGo">go:调用</button>
    <!-- 行内使用编程式导航,要省略this,否则报错 -->
    <button @click="$router.forward()">go便捷调用-forward前进一步</button>
    <button @click="$router.back()">go便捷调用-back后退一步</button>
 
  </div>
</template>
 
<script>
export default {
  name: 'RouterDemoHome',
 
  data () {
    return {
 
    }
  },
 
  mounted () {
 
  },
 
  methods: {
    handlePush () {
      // this.$router.push('hash地址'), 会产生历史记录
      this.$router.push('/about/tab2')
    },
    handleReplace () {
      // this.$router.replace('hash地址'),跳转到目标地址,并替代掉当前的历史记录
      this.$router.replace('/center/movie/3')
    },
    handleGo () {
      // this.$router.go(-1) go(正数)向前, go(负数)后退
      this.$router.go(-1)
    }
 
  }
}
</script>
 
<style scoped>
.home-container {
  height: 200px;
  background-color: rgb(236, 13, 207);
  width: 100%;
}
 
</style>

全局路由导航前置守卫

前置守卫的三种跳转方式

1.当前跳转满足跳转条件,则直接调用next()放行。
2.当前跳转不满足跳转条件,需要跳转到登录进行登录认证,则调用next('/login')进行跳转。
3.当前跳转不满足跳转条件,需要跳转到当前页面,刷新当前页,则调用next(false)进行刷新。
router.beforeEach:每次路由跳转之前会调用这个路由守卫回调方法。
可以在前置守卫中添加权限控制,比如只有localStore中保存了登录cookie,才进行方向,允许进入首页。
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import Vue from 'vue'
import Router from 'vue-router'
import About from '@/components/About/About.vue'
import Center from '@/components/Center/Center.vue'
import Home from '@/components/Home/Home.vue'
import Tab1 from '@/components/Tabs/Tab1.vue'
import Tab2 from '@/components/Tabs/Tab2.vue'
import Movie from '@/components/Movie/Movie.vue'
import Main from '@/components/Main/Main.vue'
import Login from '@/components/Login/Login.vue'
 
// 将Router安装为Vue的插件
Vue.use(Router)
 
// 创建路由的实例对象
const router = new Router({
 
  routes: [
    // 地址重定向,当跳转的URL地址没有对应组件时,那么就会强制跳转到另一个地址
    { path: '/', redirect: '/home' },
    // 路由匹配规则,实例对应是根据匹配规则,从上到下逐条匹配的
    { path: '/home', component: Home },
    // 嵌套路由,就是在对应路由容器配置项上增加children属性, 然后在这个子路由配置上增加嵌套子路由的配置。
    // 嵌套子路由的path配置无需是/开头,默认router会自动添加
    {
      path: '/about',
      component: About,
      // 默认子路由方法1:设置父路由的重定向地址
      // redirect: '/about/tab1',
      children: [
        // { path: 'tab1', component: Tab1 },
        // 默认子路由方法2:在父路由的children中,设置默认路由的path:'', 这样表示父路由默认展示这个子路由
        { path: '', component: Tab1 },
        { path: 'tab2', component: Tab2 }
      ]
    },
    {
      path: '/center',
      component: Center,
      children: [
        // id部分是可变路由的参数部分,它是随参数变化的。
        { path: 'movie/:mid', component: Movie, props: true }
      ]
    },
    { path: '/login', component: Login },
    { path: '/main', component: Main }
  ]
})
 
// 全局路由守卫,当每次路由跳转时,会先调用这个回调函数,判断是否可以继续跳转
router.beforeEach((to, from, next) => {
  /* must call `next` */
  console.log(to)
 
  if (to.path === '/main') {
    const token = localStorage.getItem('login-token')
    if (token) {
      next()
    } else {
      next('/login')
    }
  } else {
    // next:放行,如果运行路由跳转,则需要调用next()
    next()
  }
})
 
export default router

vue-router生命周期

1
2
3
4
5
6
7
1.全局beforeEach: 一般用来做权限控制。
2.路由中beforeEnter: 用的不多
3.组件里调用 beforeRouteEnter: 这个方法里面没有this
4.全局 router.resolve
5.全局 afterEach
6.调用组件的 beforeRouterLeave: 离开是提醒,是否提交表单,是否关注等等
7.beforeRouterUpdate 用在路由参数更新了,但是路由没有更新时使用。

 

 
 
posted @   滴水微澜  阅读(172)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2016-01-07 KVC的特殊用法
点击右上角即可分享
微信分享提示