【精选】Router路由详解

文章正文
发布时间:2023-11-21 05:22

Router是vue生态系统里的内容,需要单独安装,或在搭建脚手架的时候配置路由(一般默认历史模式就可以),注意路由是安装在在生产模式下的

以下代码是安装完成之后自动生成的,以及手动添加了一个user组件:

创建路由构造器(在router文件夹的index.js中引入创建路由的组件) import { createRouter, createWebHistory } from 'vue-router';

 创建路由实例(index.js) const router = createRouter({ history: createWebHistory(process.env.BASE_URL), //历史模式 routes, //路由规则 }); export default router; //将路由缺省暴露出去,其他文件才可访问

创建路由映射(index.js) // import About from '../views/About' import Home from '../views/Home' //引入需要用的组件 import User from '../views/User' //路由表映射 const routes = [ { path: '/', name: 'Home', component: Home, //设置对应路径要加载的组件 }, { path: '/about', name: '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'), //懒加载,下面会讲 }, { path:'/user', component:User } ]

启动路由(在main.js中引入路由) import router from './router'; //默认会去找index文件,如果改名了,则需要手动把名引进来 createApp(App).use(store).use(router).mount('#app');

使用router-link指令使用路由(App.vue) <!--to中写的路径会在路由表映射中进行匹配,然后加载对应的组件--> <router-link to="/">首页</router-link>| <router-link to="/about">关于我们</router-link>| <router-link to="/user">个人中心</router-link> router-link类似于超链接,是vue提供的在本站跳转页面使用,也具有一些属性例如target,其中to属性设置的路径会在路由表中进行匹配,然后加载对应组件,同时路径会显示在地址栏中。

在默认生成的App.vue的css样式中,.router-link-exact-active用来设置按钮的激活状态样式,可以进行更改。

另外,router-link的class用来设置普通的样式,clas-active设置激活时的样式: <router-link class="bg" target="_blank" active-class="active" to="/">首页</router-link>

使用<router-view>标签渲染组件(App.vue),这样一个简单的路由就配置好了 <router-view /> <!-- 显示请求过来的页面 -->

注意:

Router模式切换

20210928173748330.png

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

 引入Hash模式:

import { createRouter, createWebHistory } from 'vue-router';

使用:

const router = createRouter({ // history: createWebHistory(process.env.BASE_URL), //历史模式 history:createWebHashHistory(process.env.BASE_URL), //Hash模式 routes, //路由规则 }); 懒加载

默认是在上方导入组件,然后下面使用组件

20210928172420301.png

但是这样会出现一个问题,用webpack打包时会把所有组件打包在一个js文件中,我们加载的时候会把所有组件都加载一遍,如果组件很多的话就会很耗时间,所以我们使用懒加载的形式,这样就会在访问某个路径的时候再去加载对应组件,打包时也会成为单独的js文件:

//懒加载 const Home=()=>import('../views/Home') const User=()=>import('../views/User') //路由表映射 const routes = [ { path: '/', name: 'Home', component: Home, }, { path: '/about', name: 'About', component: About }, { path:'/user', component:User } ] 自定义router-link

router-link默认是超链接的样式,但是我们在开发中如果需要一些其他的样式,就需要自定义router-link了

我们参考vue的官网,可以使用插槽的形式自定义router-link:

<router-link to="/about" v-slot="{navigate}"> <button @click="navigate" @keypress.enter="navigate" role="link">关于我们</button> </router-link>

也可以使用vue内置的全局属性$router进行操作:

<!-- 通过$router.push()向路由里加路径,相当于前进 --> <button @click="$router.push('/user')">个人中心</button> <!-- 通过$router.go()后退 --> <button @click="$router.go(-1)">返回</button>

如果我们要设置按钮的激活状态,那就设置样式,这里注意是当前路由,用$route:

<button :class="{active:$route.path=='/user'}" @click="$router.push('/user')">个人中心</button> <!-- $route.path表示取当前的路由 --> .active{ color: red !important; } 命名视图(不常用)

如果我们在一个页面中有多个子页面,那就需要设置多个router-view了,但是如果只放多个标签上去,那这多个标签都会显示相同的页面,这里就需要给router-view命名来区分了

<!-- 起名时要和组件名字相同 --> <router-view class="one" name="User"></router-view> <router-view class="two"></router-view> <router-view class="three" name="About"></router-view>

 我们还要更改路由表里路径对应的组件(以下表示路由为首页时,不仅加载首页还可以加载其他页面),其余路径没有更改的还是显示默认的页面

{ path: '/', name: 'Home', // component: Home, components: { default:Home, // 如果router-view没有取名,就会加载默认的Home组件 About, User, }, },

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

  二. 嵌套路由(子路由)

我们在开发时,难免会使用到例如页面其他部分不变,点击菜单进行子页面的变化,此时就需要用到嵌套路由

 在对应路径下加children:

{ path: '/user', component: User, children:[ { path:'', //设置加载user页面时默认加载的页面 component:MySetting }, { // 以/开头的嵌套路径会被当做根路径,所以子路由不用加/ // 主路由会被自动添加到子路由前,所以子路由不用重新声明主路由的path了 path:'order', component:MyOrder }, { path:'setting', component:MySetting } ] }

在对应页面使用路由:

<template> <div> 个人中心页面 <br /> <div class="menu"> <ul> <li><router-link to="/user/order">我的订单</router-link></li> <li><router-link class="router-link-exact-active" to="/user/setting">个人设置</router-link></li> <!-- 这里我们用class="router-link-exact-active"设置一下按钮的激活状态 --> </ul> </div> <div class="content"> <router-view></router-view> </div> </div> </template>

当点击个人中心时,默认就会显示个人设置并激活按钮

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

 

三. 参数传递

我们在进行一些页面访问的时候,有时候页面模板不变化,只是数据的变化,这时候只需要传递参数更改数据,用同一个模板就可以

传递参数有两种类型:params和query

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

在路由表中配置:

children: [ { //:后面的相当于变量,因为路径是page/id,所以page后面要加/ path: 'page/:id', //加:是动态配置 component: MyPage }, ]

在页面中定义一个数据源,然后遍历取出id,动态绑定to,这样就会加载同一个组件,显示不同数据:

<ul> <li v-for="item in articles" :key="item"><router-link :to="'/user/page/'+item.id">{{item.title}}</router-link></li> </ul>

MyPage页面接收数据:

<template> <div> <h2>这是文章的模板</h2> 文章ID:{{pageid}} </div> </template> <script> export default { name:"MyPage", computed:{ pageid(){ return this.$route.params.id //获取当前路由参数的id } } } </script>

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

 

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

配置路由:

children: [ { path: 'article', //正常配置 component: MyArticle }, ]

 进行参数的传递,传递的参数是以字符串拼接的方式显示在路径中,我们可以动态绑定to,使用query以对象的格式传递参数:

<li><router-link to="/user/article?name=111&age=10">文章一</router-link></li> <li><router-link :to="{path:'/user/article',query:{name:'hello',age:100}}">文章二</router-link></li>

也可以应用于自定义的router-link

<button @click="$router.push({path:'/user/article',query:{name:'hello',age:100}})">文章三</button>

MyArticle页面接收参数:

<template> <div> 这是文章的页面:<br> name:{{$route.query.name}}<br> age:{{$route.query.age}}<br> </div> </template>

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

  四. 重定向和别名 重定向

当我们访问一个路由的时候,想从当前路由跳转至另外一个路由,这时就需要用到重定向

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

配置路由,用redirect将/home路由重定向至/:

const routes = [ { path: '/', name: 'HomeRoot', component: Home, }, { path: '/home', name: 'Home', redirect:'/', component: Home, }, ]

也可用name指定:

const routes = [ { path: '/', name: 'HomeRoot', component: Home, }, { path: '/home', name: 'Home', // redirect:'/', redirect:{name:'Homeroot'}, component: Home, }, ]

 跳转还支持函数的格式:

//query传参 { path: '/user', component: User, children:[ { path: 'page/:id', redirect:to=>{ //访问这个路径的时候就会跳转至article页面,同时将参数传递过去 return {path:'article',query:{name:'zhangsan',age:10}} }, component: MyPage }, { path: 'article', component: MyArticle }, ] }, //params传参 { path: '/user', component: User, children:[ { path: 'page/:id', // $route = to redirect:to=>{ return {path:'article',query:{name:'zhangsan',age:to.params.id}} }, component: MyPage }, { path: 'article', component: MyArticle }, ] },

此时我们访问/home路径,显示的页面就会被重定向至/路径

<router-link class="bg" active-class="active" to="/home">首页</router-link>| 别名

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

在路由中配置,用alias取别名,这样在用户也可以输入别名来访问这个路径:

{ path: '/about', name: 'About', alias:['/a','/b','/c'], component: About },

当路径中有参数时,取别名也要传递参数:

{ path: '/user', component: User, children:[ { path: 'page/:id', alias:['p/:id','x/:id'], component: MyPage } ] }

五. 导航守卫

导航守卫主要用来通过跳转或取消的方式守卫导航。

当我们在跳转页面时,跳转前和跳转后如果需要做一些特殊的操作,就需要用到导航守卫

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

在路由中进行配置,这里我们给每一个页面加上一个源数据meta,这样可以根据选择的页面显示其对应的title,在vue2中beforeEach还有第三个参数next,用来操作另一个页面的跳转:

const routes = [ { path: '/', name: 'Homeroot', component: Home, meta:{ //设置源数据 title:'1111111111111' } }, { path: '/home', name: 'Home', // redirect:'/', redirect:{name:'Homeroot'}, component: Home, meta:{ title:'222222222222' } }, ] //创建路由 const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes, }); //前置守卫:跳转之前执行,如可以在页面跳转之前先进入另一个页面 router.beforeEach((to,from)=>{ console.log(to.fullPath); //获取即将进入的路由 console.log(from.fullPath); //获取离开的路由 document.title=to.meta.title; //获取源数据的内容,设置为对应页面的title })

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

//后置钩子:如页面请求失败时,可以跳转至其他页面 router.afterEach((to,from)=>{ console.log("to---",to.fullPath); console.log("from---",from.fullPath); })

以上是全局导航守卫,导航守卫还包括一些独享的,直接在路由的配置对象上定义防护(官网有说明):

const routes = [ { path: '/', name: 'Homeroot', component: Home, beforeEnter: (to, from) => { return false; } }, ]

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

 keep-alive和vue-router结合使用

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

当一个组件被创建之后用keep-alive缓存就不会被销毁,vue3中用插槽的方式设置缓存

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAWGludF8=,size_20,color_FFFFFF,t_70,g_se,x_16

<router-view v-slot="{ Component }"> <transition> <keep-alive exclude="About,User"> <!--exclude排除不需要缓存的组件,可以写多个--> <component :is="Component"></component> </keep-alive> </transition> </router-view>  beforeRouteLeave

如果我们在离开一个页面进入另一个页面,想要保留页面离开前的状态,以便回来继续访问,可以使用beforeRouteLeave

 定义path,用来存放离开时的路径:

path:'/user'

 离开页面时,将离开时的路径赋给path:

<script> export default { name: "User", data() { return { articles:[ {id:10,title:'这是文章一'}, {id:11,title:'这是文章一'}, {id:12,title:'这是文章一'}, {id:13,title:'这是文章一'}, {id:14,title:'这是文章一'}, ], path:'/user' } }, created() { console.log('User组件被创建'); }, unmounted() { console.log('User组件被销毁'); }, activated() { console.log('User##keep-alive缓存组件激活时调用'); }, deactivated() { console.log('User##keep-alive缓存组件停用时调用'); }, beforeRouteLeave (to, from) { // 获取页面离开时的路由 // console.log(from.fullPath); this.path=from.fullPath; } }; </script>

 再次访问页面时,也就是激活组件时,将路由跳转至该页面,就可以恢复访问了

activated() { console.log('User##keep-alive缓存组件激活时调用'); this.$router.push(this.path) },

 

首页
评论
分享
Top