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模式切换引入Hash模式:
import { createRouter, createWebHistory } from 'vue-router';使用:
const router = createRouter({ // history: createWebHistory(process.env.BASE_URL), //历史模式 history:createWebHashHistory(process.env.BASE_URL), //Hash模式 routes, //路由规则 }); 懒加载默认是在上方导入组件,然后下面使用组件
但是这样会出现一个问题,用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-linkrouter-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, }, },我们在开发时,难免会使用到例如页面其他部分不变,点击菜单进行子页面的变化,此时就需要用到嵌套路由
在对应路径下加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>当点击个人中心时,默认就会显示个人设置并激活按钮
三. 参数传递
我们在进行一些页面访问的时候,有时候页面模板不变化,只是数据的变化,这时候只需要传递参数更改数据,用同一个模板就可以
传递参数有两种类型:params和query
在页面中定义一个数据源,然后遍历取出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>
进行参数的传递,传递的参数是以字符串拼接的方式显示在路径中,我们可以动态绑定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>当我们访问一个路由的时候,想从当前路由跳转至另外一个路由,这时就需要用到重定向
也可用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>| 别名在路由中配置,用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 } ] }五. 导航守卫
导航守卫主要用来通过跳转或取消的方式守卫导航。
当我们在跳转页面时,跳转前和跳转后如果需要做一些特殊的操作,就需要用到导航守卫
以上是全局导航守卫,导航守卫还包括一些独享的,直接在路由的配置对象上定义防护(官网有说明):
const routes = [ { path: '/', name: 'Homeroot', component: Home, beforeEnter: (to, from) => { return false; } }, ]如果我们在离开一个页面进入另一个页面,想要保留页面离开前的状态,以便回来继续访问,可以使用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) },