vue-router——08.07

it2025-05-02  17

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传值。不需要在routes的path属性上配置。

获取路由的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的防护措施。对于beforeRouteUpdate和beforeRouteLeave,this已经可用,因此不需要传递回调,因此不支持。

七、给路由添加过渡

可以用 <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组件)里边的“异步组件”。

最新回复(0)