前端路由:在架构一个网络时,路由器和交换机是非常重要的,事实上,路由器主要维护的是一个映射表,映射表会决定数据的流向。
前端路由是通过监听URL的改变进行与内容的映射
url的hash也就是锚点(#),本质上是改变window.location的herf属性,我们可以通过直接赋值location.hash来改变herf,但是页面不刷新
<body> <div id="app"> <a href="/#home">home</a> <a href="/#about">about</a> </div> <div class="box"></div> <script> const box = document.querySelector('.box') window.addEventListener('hashchange', () => { switch (location.hash) { case '#home': box.innerHTML = "home" break; case '#about': box.innerHTML = "about" break; default: box.innerHTML = 'default' } }) </script> </body>
history接口是html5新增的,它有六种模式改变url而不刷新页面:
replaceState:替换原来的路径
pushState:使用新的路径
popState:路径的回退
go:向前或向后改变路径
forward:向前改变路径
back:向后改变路径
vue-router是基于路由和组件的
路由用于设定访问路径,将路径和组件映射起来,在vue-router的单页面应用中,页面的路径的改变就是组件的切换
步骤:
1、新建一个pages文件夹,内部新建两个文件home.vue和about.vue
2、 新建一个router文件,其内部用来存放路由映射
import { createRouter,createWebHistory,createWebHashHistory } from "vue-router" const routes=[ { path:'/home', component:()=>import("../pages/home.vue") }, { path:'/about', component:()=>import("../pages/about.vue") } ] // 创建路由对象 const router=createRouter({ routes, history:createWebHistory() //设置路由模式 }) export default router
3、在main.js中使用router
import { createApp } from 'vue' import App from './App.vue' import router from "../src/router/index" const app=createApp(App) app.use(router) app.mount('#app')
4、在App.vue中使用<router-view>用来显示路由,其作用就是占位,当匹配到路由的时候就会显示对应的组件
<template> <div> <h2>app1</h2> <router-view></router-view> <h2>app2</h2> </div> </template>
此时输入路由信息就可以看到
但是此时需要手动输入
所以我们需要点击按钮的时候进行跳转
vue-router提供一个内置组件<router-link>,其中的属性to用于跳转的路由
<template> <div> <h2>app1</h2> <router-link to="/home">home</router-link> <router-view to="/about">about</router-view> <h2>app2</h2> </div> </template>
此时就可以实现点击进行路由跳转了
实际上<router-link>会被解析成两个a元素
const routes=[ { path:'/', redirect:'home' }, { path:'/home', component:()=>import("../pages/home.vue") }, { path:'/about', component:()=>import("../pages/about.vue") } ]
此时直接打开localhost:8080会被重定向到home首页
如果想要路由上有#,可以使用createWebHashHistory模式
const router=createRouter({ routes, history:createWebHistory() //设置路由模式 })
router-link上可以配置很多属性:
to属性:一个字符串或者是一个对象
replace属性:设置replace属性的话,当点击的时候,会调用router.replace(),而不是router.push(),此时就不可以进行返回操作
active-class属性:设置激活a元素后应用的class,默认是router-link-active
.router-link-active{ color: red; }
可以使用active-class进行修改
<router-link to="/home" active-class="active">home</router-link> <router-link to="/about" active-class="active">about</router-link>
.active{ color: red; }
可以通过name进行路由的跳转
const routes=[ { path:'/', redirect:'home' }, { path:'/home', name:'home', component:()=>import("../pages/home.vue") }, { path:'/about', name:'about', component:()=>import("../pages/about.vue") } ]
这里可以增加任何数据
{ path:'/about', name:'about', component:()=>import("../pages/about.vue"), meta:{ name:'tom', age:19 } }
此时我们在路径上写一个name
{ path:'/user/:name', name:'user', component:()=>import("../pages/user.vue") },
如果此时我们这样写,进行路由跳转是由问题的,点击路由的时候不会有内容显示,
在跳转路由的时候需要携带参数进行跳转
<router-link to="/user/tom" active-class="active">user</router-link>
此时就是可以进行正常的显示的
我们可以将通过路由传递过来的参数进行展示
created(){ console.log(this.$route) }
如果此时我们输入的路由没有对应的组件
此时就可以这样做,新建一个not.vue的文件
<template> <div> <h2>not found</h2> </div> </template>
router.js文件
{ path:'/:pathMatch(.*)',//0个多个任意字符匹配不到的时候使用该组件 component:()=>import("../pages/not.vue") }
此时在打开的页面输入没有的路由是就可以看到,我们也可以输出this.$route查看一下
新建两个文件message.vue和shop.vue,配置路由
{ path:'/home', name:'home', component:()=>import("../pages/home.vue"), children:[ { path:'message', component:()=>import("../pages/message.vue") }, { path:'shop', component:()=>import("../pages/shop.vue") }, ] },
在home.vue标签中使用router-view用来显示
<router-view/>
router-link通过一个作用域插槽暴露底层的定制能力
href
:解析后的 URL。将会作为一个 <a>
元素的 href
属性。如果什么都没提供,则它会包含 base
。route
:解析后的规范化的地址。navigate
:触发导航的函数。 会在必要时自动阻止事件,和 router-link
一样。例如:ctrl
或者 cmd
+ 点击仍然会被 navigate
忽略。isActive
:如果需要应用 active class,则为 true
。允许应用一个任意的 class。isExactActive
:如果需要应用 exact active class,则为 true
。允许应用一个任意的 class。注意:把 custom
配置传递给 <router-link>
,以防止它将内容包裹在 <a>
元素内。
<router-link custom to="/home" v-slot="{ href, route, navigate, isActive, isExactActive }">{{href}}</router-link>
<router-link custom to="/home" v-slot="{ href, route, navigate, isActive, isExactActive }">{{route}}</router-link>
<router-link custom to="/home" v-slot="{ href, route, navigate, isActive, isExactActive }">{{navigate}}</router-link>
<router-link custom to="/home" v-slot="{ href, route, navigate, isActive, isExactActive }">{{isActive}}</router-link>
<router-link custom to="/home" v-slot="{ href, route, navigate, isActive, isExactActive }">{{isExactActive}}</router-link>
router-view也提供的有插槽,可以用于<transition>和<keep-alive>组件来包裹路由组件
Component:要渲染的组件
route:解析出的标准化路由对象
动画案例:
<router-view v-slot="props"> <transition name="anmition"> <component :is="props.Component"></component> </transition> </router-view>
.anmition-enter-form,.anmition-leave-to{ opacity: 0; } .anmition-enter-active,.anmition-leave-active{ transition: opacity 1s ease; }
通过判断条件使用router.addRoute方法进行添加路由
const dynamic={ path:'/dynamic', component:()=>import("../pages/dynamic.vue") } if(true){ router.addRoute(dynamic) }
删除路由有三种方式
第一种,添加一个name相同的路由
router.addRoute({path:'/home',name:'home',component:home}); // 这将会删除之前已经添加的路由,因为他们有相同的名字并且名字必须是唯一的 router.addRoute({path:'/about',name:'home',component:about})
第二种,通过removeRoute方法,传入路由的名称
router.addRoute({path:'/home',name:'home',component:home}); router.removeRoute('home')
第三种,如果我们在添加完路由之后,其实是有一个返回值的,返回值本身是一个函数,如果调用这个函数,原来添加的路由就会被删除掉
const remove=router.addRoute({path:'/home',name:'home',component:home}); remove()
router.hasRoute():检查路由是否存在
router.getRoutes():获取一个包含所有的路由记录的数组
导航守卫主要用来通过跳转或取消的方式守卫导航
全局前置守卫beforeEach是在导航触发时会被回调的
一个接收三个参数
to:Route对象,即将跳转到的route对象
from:Route对象,从哪一个路由对象对象跳转过来的
next:已抛弃
// 导航守卫 router.beforeEach((to,from)=>{ console.log(to,'to') console.log(from,'from') })
点击一个about就可以看到
如果此时点击路由的时候不希望进行跳转可以return false,此时在点击路由的时候就不会进行路由跳转了。
router.beforeEach((to,from)=>{ return false })
返回问题:
false:不进行路由跳转
undefined或者不写返回值:进行默认导航
字符串:返回的字符串应该是一个路径,返回的什么字符串就会跳转到该字符串所表示的路径
对象:类似于router.push({path:"/login",query:'......'})