vue-router——08.07

本文详细介绍了Vue.js的官方路由器VueRouter的使用,包括route、routes和router的区别,客户端路由原理,VueRouter的安装、配置、路由重定向、别名、动态传参、嵌套、编程式导航、路由守卫和过渡效果。同时,讲解了如何实现路由延迟加载,提升应用性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue Router 是Vue.js的官方路由器。

学习Vue Router之前,先了解路由中的三个基本的概念 route, routes, router

1、 route,它是一条路由,由这个英文单词也可以看出来,它是单数, Home按钮 => home内容, 这是一条route, about按钮 => about 内容, 这是另一条路由。

2、 routes 是一组路由,把上面的每一条路由组合起来,形成一个数组。[{home 按钮 =>home内容 }, { about按钮 => about 内容}]

3、 router 是一个机制,相当于一个管理者,它来管理路由。因为routes 只是定义了一组路由,它放在哪里是静止的,当真正来了请求,怎么办? 就是当用户点击home 按钮的时候,怎么办?这时router 就起作用了,它到routes 中去查找,去找到对应的 home 内容,所以页面中就显示了 home 内容。

4、客户端中的路由,实际上就是dom 元素的显示和隐藏。当页面中显示home 内容的时候,about 中的内容全部隐藏,反之也是一样。客户端路由有两种实现方式:基于hash 和基于html5 history api。(一般使用history)

一、使用 vue-router

1、安装vue-router

cnpm install --save-dev vue-router

2、src目录下新建一个router.js 文件定义router, 就是定义 路径到 组件的 映射。

引入vue-router,并关联vue-router到vue:

 import Vue from "vue";
 import vueRouter from "vue-router";
 Vue.use(vueRouter);

引入组件:

import Home from './components/Home'
import Regest from './components/Regset'
import Login from './components/Login'
import Send from './components/Sendmsg'
import Sendget from './components/Sendget'

配置路由节点

const routes=[
    {
      path: "/",
      component: Home,
      name: "homeinfo",
      //局部守卫
      beforeEnter: (to, from, next) => {
        console.log(to, from);
        next();
      }
    },
    { path: "/regest", component: Regest, name: "regestinfo" },
    {
      path: "/login/:id",
      component: Login,
      name: "logininfo",
      alias: "/userlogin",   //alias  属性为命名别名
      //路由嵌套
      children: [
        {
          path: "user",
          component: User
        }
      ]
    },
    //用户输入的地址不存在   默认指向那个路径
    { path: "*", redirect: "/" },
    { path: "/user", redirect: "/login" },
    //根据name属性重定向
    { path: "/list", redirect: { name: "logininfo" } },
    //配置路由的动态传参
    { path: "/sendMsg/:id/:name", component: Send, name: "send" },
    { path: "/Sendget", component: Sendget, name: "sendget" }
 ];
 
const router = new vueRouter({
  routes,
  mode: "history" //修改路由路径的模式  默认hsl模式 #/    history  正常的路径
});

暴露出 router:

export default router;

3、在main.js里边引入路由模块,并注入到vue根实例中

引入路由模块:

import router from "./router.js"    
// import router 的router 一定要小写, 不要写成Router, 否则报 can't match的报错

注入到根实例:

new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

4、app模板内部写路由的入口 <router-link > 和出口 </router-view>

(1)路由入口:
<router-link> 定义点击后导航到哪个路径下,默认会被渲染成一个<a>标签;

<router-link to="/regest"> regest </router-link> 

(2)路由出口:
对应的组件内容渲染到<router-view>中;

<router-view></router-view>

(3)路由入口路径的动态绑定:

HTML代码:

<router-link v-for="(item,index) in menu" :key="index" :to="item.action">{{item.name}}</router-link>

JavaScript代码:

  data() {
    return {
      menu: [
        { name: "home", action: "/" },
        { name: "regest", action: "/regest" },
        { name: "login", action: "/login/10086" },
      ],
    };
  },

二、路由的重定向 redirect 和别名 alias

1、重定向

重定向是指用户访问时/a,URL将被替换/b,然后与匹配/b
重定向也在routes配置中完成,使用redirect属性。

(1)用户输入的地址不存在,默认指向某个路径:

{ path: "*", redirect: "/" }

(2)用户输入地址,重定向到其它地址:

{ path: "/user", redirect: "/login" }

(3)根据name属性重定向:

{ path: "/list", redirect: { name: "logininfo" } }

2、别名

/a 设置别名为 /b :表示用户访问/b时,URL保持/b不变,但将被匹配/a路由。

别名也在routes配置中完成,使用alias属性。

	{
      path: "/login",
      component: Login,
      name: "logininfo",
      alias: "/userlogin",
    }

三、路由的传参

1、路由动态传参

在配置routes时,直接在path属性上配置参数。

一旦设置为动态路由传参,调用路由时就必须传递参数,否则访问不到。

routes里边配置参数:

{ path: "/sendMsg/:id/:name", component: Send, name: "send" }

组件里边获取值:在this.$route 对象上获取(this.$route.params)。

this.$router 获取的路由对象,可以实现路由跳转。

    mounted(){
        //组件挂在完成之后去获取路由的动态传参
        console.log(this.$route.params);
    },

2、路由get传值

路由get传值,是直接在路径上写传值,类似原生js里边的get传值。不需要routespath属性上配置。

获取路由的get传值:this.$route.query

    mounted(){
        //获取路由的get传值
        console.log(this.$route.query);
    },

3、在路由入口<router-link> 上进行路由传值绑定

	<!-- 路由动态传值、get传值绑定 -->
    <router-link :to="`/sendMsg/${id}/${name}`">sendMsg</router-link>    
    <router-link :to="`/Sendget?id=${id}&name=${name}`">sendMsg</router-link>
    
    <!-- get路由传值  还可以写成下面这个格式 -->
    <router-link :to="{path:'/Sendget',query:{id:id,name:name}}">sendget</router-link>

4、对参数变化做出反应

使用带参数的路由时要注意的一件事是,当用户从导航/user/foo/user/bar时,将重用相同的组件实例。由于两个路由都呈现相同的组件,因此这比销毁旧实例然后创建新实例更有效。但是,这也意味着将不会调用组件的生命周期钩子

要对同一组件中的参数更改做出反应,只需观察$route对象即可:

watch:{
    $route(from,to){
        if(to.name==from.name)
        {
            console.log("同一个路由不同参数",from,to);
            //这里可以根据参数变化手动更新相关数据
        }
    }
}

或者,使用2.2中引入的beforeRouteUpdate 导航卫士:

const User = {
  template: '...',
  beforeRouteUpdate (to, from, next) {
    // react to route changes...
    // don't forget to call next()
  }
}

四、路由的嵌套

真正的应用程序用户界面通常由嵌套在多个级别的组件组成。App主模板的<router-view>是路由的顶级出口,它使组件与顶层路线匹配,同样,App模板中渲染的组件也可以包含自己的 <router-view>,即:子路由。(注意:只有根路径在routes里边配置的时候,path属性值才需要加“/”)

  routes: [
    {
      path: '/user/:id', component: User,
      children: [
        // UserHome will be rendered inside User's <router-view>
        // when /user/:id is matched
        { path: 'userhome', component: UserHome },

        // ...other sub routes
      ]
    }
  ]

如果要将二级路由设为默认路由(进入一级路由后直接加载该二级路由),将二级路由的path 属性值设为空即可 path:" "

五、编程式导航

除了上边提到的<router-link>,通过点击实现路由跳转;也可以通过事件、逻辑代码实现路由跳转,这就是编程式导航。

编程式导航不能跨级跳转。只能同级或上一级、下一级。

1、this.$router.push()

在Vue实例内部,可以访问到路由器实例$router。因此,可以通过this.$router.push() 方法航到其他URL。

此方法将新条目推入历史记录堆栈,因此,当用户单击浏览器后退按钮时,它们将被带到先前的URL。

this.$router.push() 的参数:
参数可以是字符串路径,也可以是位置描述符对象。

// literal string path
router.push('home')

// object
router.push({ path: 'home' })

// named route
router.push({ name: 'user', params: { userId: '123' } })

// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' } })

2、this.$router.replace()

就像router.push一样,唯一的区别是它导航时没有推送新的历史记录条目,顾名思义-它替换了当前条目。

3、this.$router.go(n)

此方法采用单个整数作为参数,该参数指示在历史记录堆栈中前进或后退多少步,类似于window.history.go(n)

以上几种方法的使用:

<template>
<div id="user">
    user
    <button @click="goroute">点击进入**页面</button>
    <button @click="goback">点击回退</button>
</div>
</template>

<script>
export default {
    name:"user",
    methods:{
        goroute(){
            //this.$router.push("/login/10086");
            this.$router.replace("/login/10086");
        },
        goback(){
            this.$router.go(-1);
        }
    }
}
</script>

六、路由的安全守卫

主要用于通过重定向或取消导航来保护导航。有很多方法可以挂接到路线导航过程中:全局,每个路线或组件内。

1、全局守卫

(1)路由执行之前: router.beforeEach()

在路由触发之前可以做一些状态处理。

每当触发导航时,将按创建顺序调用全局警戒。可以异步解决保护措施,并且在解决所有挂钩之前将导航视为挂起状态。

router.beforeEach((to, from, next) => {
  console.log(to, from);
  if (to.name != "sendget") {
    next("/Sendget");  //next({padth:"/home"})
  }
  else {
    next();
  }

});

to:Route: 要导航到的目标对象;
from: Route:正在远离的当前路线;
next() 进行管道中的下一个,不写next() ,路由终止;
next(false) 终止当前路由;
next("/")next({padth:"/"})参数为路径时,重定向路由。

注意:

确保next在通过导航防护装置的任何给定遍历中,仅一次调用该函数。它可以出现多次,但前提是逻辑路径没有重叠,否则钩子将永远无法解决或产生错误。

(2)路由执行之后: router.afterEach()

注意:该钩子没有next功能,因此不会影响导航。

router.afterEach((to, from) => {
  console.log(to, from);
});

2、局部守卫:beforeEnter

可以beforeEnter直接在路由的配置对象上定义防护:(针对某个路由的私有守卫)

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

3、组件内防护

直接在组件内部写安全守卫:
beforeRouteEnter(to,from,next){}
beforeRouteUpdate(to,from,next){}
beforeRouteLeave(to,from,next){}

<script>
export default {
  name: "login",
  methods: {
  //......
  },
  
  // 组件内部的路由安全守卫
  beforeRouteEnter(to, from, next) {
    console.log("进入之前");
    //路由进入之前  当前组件没有实例化
    next((vm) => {
      console.log(vm); //vm  形参代表组件的实例
    });
  },
  beforeRouteUpdate(to, from, next) {
    //当前路由不变   参数发生变化 时触发
    console.log(this);
    next();
  },
  beforeRouteLeave(to, from, next) {
    console.log("离开之前");
    console.log(this);
    next();
  },
};
</script>

beforeRouteEnter 里边访问不到this,因为此时组件还没有实例化。

注意:
beforeRouteEnter是唯一支持将回调传递给next的防护措施。对于beforeRouteUpdatebeforeRouteLeavethis已经可用,因此不需要传递回调,因此不支持。

七、给路由添加过渡

可以用 <transition></transition> 包裹路由出口<router-view></router-view> 来为路由添加过渡(相当于给路由对应的组件添加过渡),<transition>用法同vue自定义动画,也可以使用animate.css

html:

    <transition name="fade" duration="200" mode="out-in">
      <router-view></router-view>
    </transition>

css:

<style>
.fade-leave-active {
  transition: transform 0.2s ease-in;
}
.fade-leave-to {
  transform: translatex(-100%);
}
.fade-enter-active {
  transition: transform 0.2s ease-in;
}
.fade-enter {
  transform: translatex(100%);
}
</style>

八、路由延迟加载

就是将路由里边配置的组件写成异步加载。
参考另一篇博客(vue组件)里边的“异步组件”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值