这是我参与「第四届青训营 」笔记创作活动的第30天,正好满一个月,也正好彻底完成了青训营的大项目,在这里笑庆祝一下(因为debug过程太艰辛惹T_T)。在这里介绍下大项目里使用到的vue-router。
vue-router
路由核心:改变URL但页面不进行整体刷新
路由表 - 映射表,一个路由就是一组映射 key:value (key表示路由,value表示function或component) function - 后端路由 component - 前端路由(组件,展示内容)
安装
npm install vue-router@4
src/views 一般路由组件的文件夹
使用
-
src/views 路由组件存放处 Home.vue About.vue
-
src/router/index.js 路由配置文件
//1. 定义路由组件, 也可其他文件导入
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import {createRouter,createWebHashHistory} from 'vue-router'
//2. 定义路由-路由映射表
const routes = [
{path: '/', component: Home},
{path: '/about', component: About}
]
//3. 创建路由实例并传递routes配置
const router = createRouter({
history: createWebHashHistory(),
routes,
})
//为挂载到main.js,需导出router
export default router;
- main.js入口文件引入
import { createApp } from 'vue'
import App from './App.vue'
import router from './router' //默认去找文件夹下index。js文件
const app = createApp(App)
//路由先,再挂载APP(app里需要使用router-link)
app.use(router)
app.mount('#app')
- App.vue文件
<template>
<div>
<h1>Hello App!</h1>
<p>
<!--使用 router-link 组件进行导航 -->
<!--通过传递 `to` 来指定链接 -->
<!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
</template>
<router-link to="/">Go to Home</router-link> 相当于a标签,to指向对应URL
<router-view></router-view>匹配到的组件,渲染
动态路由的匹配
路径参数:一般适用于不同id在同一组件的不同内容显示
{path: '/users/:id', component: User},
路由参数用:表示,当一个路由被匹配,它的params的值将在每个组件中暴露
选项式API: this.$route.params (this.$route表示当前路由活跃对象) params为对象,params.id
组合式API:
先引入import {userRoute} from 'vue-router'
userRoute().params.id
404
正则匹配,上面路径都未匹配到则会被匹配到404路径
{path: '/:path(.*)', component: NotFound} //正则
正则
-
动态路由必须为数字
path: "/news/:id(\\d+)"匹配不到会进入404页面 -
多个参数
path: "/news/:id+" -
可有可无参数
path: "/news/:id*"(可有多个参数)path: "/news/:id?"(最多只能跟一个参数)
嵌套路由
children属性,可用于添加子路由
{
path: '/parent',
component: Parent,
children: [{
path: 'style1',
component: Style1
},{
path: 'style2',
component: Style2
}]
},
parent.vue:
<div>
Parent
<router-link to="/parent/style1">1</router-link>
<router-link to="/parent/style2">2</router-link>
<router-view></router-view>
</div>
通过js跳转页面
router-link一点击就会跳转到相关页面, js可进行操作
route:当前活跃的路由对象 path、params...
- this.$router.push('/') //跳转到home页面
- this.$router.push({path:'/'}) //跳转到home页面,对象的方式
- this.$router.push({name: 'news', params: '123'})//路由里定义一个name,即 访问/new/123
- get请求携带的参数:thid.$router.push(path: '/about', query:{name:'wy', age:18}) //访问到/about?name=wy&age=18
替换当前位置
跳转过后历史不会记录跳转页面,而是将新页面替换该页面
操作:this.$router.push({path:'/', replace: true}) 添加replace:true
也可直接写为this.$router.replace({path:'/'})
图示:
1 -> 2(replace:true) -> 3
1 -> 3 3的往前一个历史记录为1(2被替代)
横跨历史
this.$router.go(1)//1前进1步,-1后退1步
命名路由
给路由定义一个name属性
使用:
<router-link :to="{ name:'news', params:{id:456} }">2</router-link>
命名视图
同级展示多个视图
router-view增加name属性
<router-view name="shopFooter"></router-view>
{
path: '/shop',
components: {
default: shopMain, //默认展示不需要name
shopFooter: shopFooter, //同名可以直接简写 shopFooter,
shopHead: shopHead
}
}
重定向命名
/和/home同时可访问首页
属性:redirect
{
path: '/',
redirect: '/home' //重新定向去找path
//redirect: {name} 重新定向按name寻找
//函数形式
//redirect:()
},{
path: '/home',
...
}
历史模式
- 哈希模式
history: createWebHashHistory(),
也需要import
首页/#/ : 传递url之前使用了一个哈希字符(#)
不会向浏览器发出请求,
- html5模式
history: createWebHistory(),
url看起来会更正常,但如果没有适当的服务器配置,会有404报错,需要后端配置
路由守卫
与生命周期函数很像,在发生页面跳转时就会触发函数
全局前置守卫
每个路由变化都会触发(全局)
//跳转之前函数调用
router.beforeEach((to, from, next)-<{
//to去往页面地址
//from原先页面地址
//next相当于通行证, 是个函数,调用了相当于放行(可选项)
next();
}
单独守卫(每路守卫)
{
path: '/about',
component: About,
beforeEnter: (to,from)=>{
//进入about页面才会触发
}
},
组件内守卫
与生命钩子一样
beforeRouteEnter(to, from, next){ next((vm)=>{ vm.age(相当于this) })} 路由进入前 beforePouteUpdate 路由更新前 beforeRouteLeave 路由离开组件之前
路由懒加载
js过大,加载速率会很慢
路由懒加载:需要再加载 - 动态加载 import - 静态加载
操作: component接收一个函数(promise组件)
component: ()=>import('../views/Home.vue'),
或
const Home = ()=>import('../views/Home.vue')
component: Home