Vue-router相关的知识点

Vue-router

  • Vue-router 介绍(基本的使用)
  • 脚手架里面如何使用
  • hash 模式和 history 模式
  • router-link 配置
  • 嵌套路由
  • 命名路由和命名视图
  • 重定向和别名
  • 编程式导航
  • 动态路由
  • 导航守卫

Vue-router 介绍(基本的使用)

vue-router 是 vue 技术栈(全家桶)里面的一员,它是官方给我们所提供的前端路由器。

在最早期的时候,是没有前端路由这么一个说法,以前只有后端路由。以前上网的时候,只要 url 一变化,就会向服务器发送请求。

但是现在,流行单页应用应用,其中最流行的方式就是改变一个 url 的 #(hash)后面的部分,这样可以做到 url 虽然发生了变化,但是不会向服务器发送请求。

所以说,这个时候,就需要一个前端路由了。通过前端路由来导航,决定 hash 后面的值的变化如何进行页面的导航。

接下来,我们来看一个 vue-router 的快速入门示例:

<body>
    <div id="app">
        <h1>欢迎学习 vue-router</h1>
        <div>
            <router-link to="/com1">内容1</router-link>
            <router-link to="/com2">内容2</router-link>
            <!-- 这里就是路由的出口,匹配上的组件会渲染到这个 router-view 这个位置 -->
            <router-view></router-view>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.js"></script>
    <script>
        // 1. 创建 2 个组件
        const com1 = {
            template : `<div>这是组件1</div>`
        }
        const com2 = {
            template : `<div>这是组件2</div>`
        }

        // 2. 配置我们的路由的路径
        const routes = [{
            path : '/com1',
            component : com1
        },{
            path : '/com2',
            component : com2
        }];

        // 3. 创建 router 实例
        const router = new VueRouter({
            routes
        })

        // 至此,我们的路由就创建好了,并里面指定了路由该如何跳转
        // 最后一步,就是需要将这个路由挂载到我们的 vue 实例上面

        const app = new Vue({
            router
        }).$mount('#app'); // 以渲染函数的方式进行挂载
    </script>
</body>

脚手架里面如何使用

在脚手架中使用 vue-router 的方法基本上和上面的快速入门示例相同。

首先,我们会有一个专门的 router/index.js 来书写我们的路由。里面的代码仍然是:

  1. 配置路由如何进行导航
  2. 实例话一个 router 路由的实例(里面进行相应的配置)
  3. 导出这个 router 实例
  4. 在 vue 实例中对 router 实例进行挂载

在组件中,我们可以通过 this. r o u t e 获 取 到 当 前 的 路 由 , 里 面 包 含 了 n a m e 、 p a t h 等 更 加 详 细 的 信 息 。 通 过 t h i s . route 获取到当前的路由,里面包含了 name、path 等更加详细的信息。通过 this. routenamepaththis.router 可以获取到 vue-router 实例。

例如:

mounted() {
  console.log("当前的路由器:", this.$route);
  console.log("整个路由器:", this.$router);
}

hash 模式和 history 模式

hash 模式就是我们最早使用单页应用时候的形式,一个 url 里面会有一个 #,写出来的样子大致如下:

http:localhost:3000/#/stu

可以看到,使用 hash 模式,路由里面存在一个 #,不是很美观,html 5 推出了 history 相关的 api,利用 history 相关的 api,我们可以将路由修改为历史模式,从而去除了 # 号。

http:localhost:3000/stu

在 vue-router 中,要配置 hash 模式还是 history 模式的方法非常简单,在创建 vue-router 实例的时候,有一个 mode 选项,hash 对应 hash 模式,history 对应 history 模式。

const router = new VueRouter({
  mode: 'history', // 配置路由究竟是 hash 模式还是 history 模式
  base: process.env.BASE_URL,
  routes
})

router-link 相关配置

router-link 是链接,可以导航到对应的组件(是在 router 文件里面配置的)。

首先,我们来看一下 router-link 在浏览器中的渲染是什么。

在浏览器中,router-link 会被渲染成 a 标签。

动态绑定路由的跳转,其实就是之前学过的知识,示例如下:

// tempalte
<router-link :to="test1">Home</router-link> |
<router-link :to="test2">About</router-link>

// js
<script>
export default {
  data(){
    return {
      test1 : '/',
      test2 : '/about'
    }
  }
}
</script>

通过设置 tag 值来决定最终渲染成什么标签(默认是 a 标签)

示例如下:

<router-link :to="test1" tag='p'>Home</router-link>

可以设置 router-link 的激活样式

首先,在创建 vue-router 实例的地方,添加 linkActiveClass 的键名,后面对应要应用的样式,如下:

// /src/router/index.js

const router = new VueRouter({
  linkActiveClass : 'activeClass', // 这里就是设置 router-link 激活的样式
  mode: 'history', // 配置路由究竟是 hash 模式还是 history 模式
  base: process.env.BASE_URL,
  routes
})

接下来,需要在 router-link 所在的组件位置书写相应的css样式,如下:

// App.vue

<style lang="scss">

.activeClass{
  font-size: 32px;
  color: red;
}
</style>

还可以设置 router-view 的公共样式。

首先,需要在 router-view 里面书写一个类名,例如:

<router-view class='viewClass'/>

接下来在有 router-view 的组件的 style 里面书写对应的样式即可。如下:

.viewClass {
  color: skyblue;
}

我们还可以更改触发router 的事件,默认是点击事件。要更改的话,直接在router-link上面添加 event 属性,属性值用来指定具体的事件即可。例如:

<router-link :to="test2" event="mouseover">About</router-link>

嵌套路由

在实际业务,非常常见的一个需求,就是路由的嵌套。

首先,在 router/index.js 里面进行嵌套路由的配置,嵌套路由,需要使用到 children 这个配置项。

具体配置如下:

{
    path: '/user',
    component : User,
    children : [{
      path : 'one',
      component : One
    },{
      path : 'two',
      component : Two
    }] // 这里面就是用来配置 user 的子路由
  }

接下来,既然需要 one 和 two 这两个组件,那么,就需要创建这么两个对应的组件

// one 组件如下,two 组件和 one 一样

<template>
    <div>
        this is one component
    </div>
</template>

接下来,就需要在 User 组件里面,也设置 router-link 和 router-view,代码如下:

<template>
    <div>
        这是 User 组件
        <router-link to='/user/one'>one</router-link>
        <router-link to='/user/two'>two</router-link>
        <router-view></router-view>
    </div>
</template>

命名路由和命名视图

上面我们介绍了嵌套的路由,那么在实际的开发中,可能就会存在嵌套的层数比较多。那么我们在进行导航的,可能就会存在如下的情况:

<router-link to='user/one/two/three/four'>xxx</router-link>

这个时候,我们就可以使用命名路由的方式。

用法很简单,首先,需要给配置的组件一个 name 属性,如下:


...
 children : [{
      path : 'one',
      name : 'one',  // 给该配置的组件一个 name 属性
      component : One
    },{
...

接下来,在 router-link 中,就可以使用对象的形式来进行访问:

...
 <router-link :to='{name:"one"}'>one</router-link>
...

有些时候,我们想要展示多个视图。这个时候,我们可以设置多个router-view,并且给router-view命名,加上 name 属性。

如下:

 <router-view class='viewClass' name="sider"/>
 <router-view class='viewClass' name="default"/>
 <router-view class='viewClass' name="home"/>

接下来,既然有了 3 个 router-view,那么在进行路由配置的时候,就需要指定每一个router-view渲染哪一个组件,配置如下:

{
    path: '/home',
    name: 'Home',
    components: {
      default : User,
      sider : One,
      home : Two
    }
 }

重定向和别名

所谓重定向,就是从一个路由跳转到另外一个路由。

在vue-router中,设置重定向的方法很简单,直接在routes里面进行配置即可。

...
{
    path: '/home',
    name: 'Home',
    redirect : '/about', // 重定向到 about 页面
    components: {
      default : Home,
      sider : One,
      home : Two
    }
  },
...

所谓别名,就是可以给路由的配置取一个小名。示例如下:

{
    path: '/about',
    name: 'About',
    alias : '/abc',  // 给 about 取了一个别名
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },

访问的时候,就正常像访问路由一样访问即可,如下:

<router-link to="/abc">About</router-link> 

编程式导航

前面我们所书写的导航的方式,叫做声明式导航。

所谓编程式导航,就是使用方法来进行跳转。例如:

// template
<button @click='gotoAbout'>go to about</button>

// js
 gotoAbout(){
      // 导航到 about 页面
      // 页面栈
      // this.$router.push('/about'); // 推入一个新的页面
      this.$router.replace('/about'); // 替换一个页面组件
      // 除此之外,还有诸如 back、forward、go 等方法
    }

动态路由

有些时候,我们在渲染某一个组件的时候,可能会有的需求是,渲染的组件是同一个组件,但是根据传入的状态值不同,渲染的内容不一样。

http://localhost:3000/stu

对应就应该是 stu 学生组件,这个组件是显示学生信息的。根据学生 id 的不同,学生的信息是完全不同的。

http://localhost:3000/stu/1

http://localhost:3000/stu/2

那么,在跳转到 stu 这个组件的时候,我们就需要拿到后面的动态参数,然后决定渲染哪一个信息。

具体示例如下:

首先,需要在路由配置的地方,打开动态参数,如下:

...
{
    path : '/stu/:id', // 代表有一个的动态参数,如果需要动态参数可选,那么可以加一个 ?,path : '/stu/:id?'
    component : Stu
  }
...

接下来,要渲染的组件都是 stu,那么我们就需要在 stu 组件里面首先获取到传递过来的 id,获取到之后,渲染出对应 id 的学生信息。代码如下:

// 第一次渲染 User 组件时获取当前的路由地址
  created() {
    let id = this.$route.params.id;
    console.log("created id", id);
    this.stuInfo = stus.filter(item => {
      return item.id == id;
    });
    console.log(this.stuInfo,'aaa')
  },
  // 之后对路由进行监听,如果后面的参数发生变化,会触发 $route 方法
  // to 为新的路由,from 为旧的路由
  watch: {
    $route(to, from) {
      let id = to.params.id;
      console.log("watch id", id);
      this.stuInfo = stus.filter(item => {
        return item.id == id;
      });
    }
  }

获取动态路由的后面的参数的时候,还可以使用 props 来进行获取。

具体步骤,首先需要在路由配置里面,开启 props,如下:

{
    path : '/stu/:id', // 代表有一个的动态参数,如果需要动态参数可选,那么可以加一个 ?,path : '/stu/:id?'
    component : Stu,
    props : true // 开启 props,也就是说,回头组件在获取 id 的时候,可以通过 props 来获取
 }

接下来,在组件中,就可以通过 this.id 的方式来进行 id 的获取。

props :['id'], // 通过 props 获取到 id
  // 第一次渲染 User 组件时获取当前的路由地址
  created() {
    let id = this.id;
    console.log("created id", id);
    this.stuInfo = stus.filter(item => {
      return item.id == id;
    });
    console.log(this.stuInfo,'aaa')
  },
  // 之后对路由进行监听,如果后面的参数发生变化,会触发 $route 方法
  // to 为新的路由,from 为旧的路由
  watch: {
    $route() {
      let id = this.id;
      console.log("watch id", id);
      this.stuInfo = stus.filter(item => {
        return item.id == id;
      });
    }
  }

导航守卫

所谓导航守卫,就是只一个路由的一系列生命周期过程。当我们从一个路由导航到另外一个路由的时候,会经历一系列的生命周期,那么,我们可以在这些生命周期所对应的钩子函数来做一些额外的事儿。

那么,一次完整的导航解析包含的流程如下:

一次完整的导航解析流程如下:

  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫(2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

下面是一个全局导航守卫的快速入门示例:

router.beforeEach((to,from,next)=>{
  console.log('现在进入了 beforeEach');
  console.log('to:',to);
  console.log('from:',from);
  next(); // 必须要调用 next 方法,才会进入下一个组件
})

next 方法可以接收参数,具体的参数信息如下:

next 方法的参数有以下几种可能:

  • next( ):进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed(确认的)。

  • next(false):中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

  • next(’/’) 或者 next({ path: ‘/’ }):跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-linkto proprouter.push 中的选项。

  • next(error):(2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError 方法中注册过的回调。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值