vue2笔记12 router路由
实现SPA应用(单一页面,局部更新)前端路由(根据浏览器路径显示对应组件)
安装
注意不屑@3会默认安装4版本,需要vue3
npm i vue-router@3
搭建router环境
创建router
./router/index.js
import VueRouter from "vue-router";
// 路由配置,注意拼写
const routes = [];
// 创建并暴露router
export default new VueRouter({
routes
})
创建vm传入router配置
main.js
import Vue from 'vue'
import App from './App.vue'
// 引入并应用路由插件
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import router from "@/router";
new Vue({
render: h => h(App),
// 传入路由器配置
router: router
}).$mount('#app')
配置路由
./router/index.js
const routes = [
{
path: '/page1',
component: Page1,
// 多级路由
children: [
{
// 相对路径
path: '1',
component: Page1_1
},
{
// 命名路由
name: 'p1-2',
path: '2',
component: Page1_2,
children: [
{
// 使用路径参数,必须使用命名路由
name:'p1-2-d',
path: 'details/:id/:title',
component: Page1_2_Details
}
]
}
]
}, {
path: '/page2',
component: Page2,
children: [
{
// 使用查询参数
path: 'details',
component: Page2_Details
}
]
}
];
注,使用多级命名路由时,名称需要唯一,否则会导致各种意外的跳转
使用路由跳转
<!-- 多页面跳转使用a标签 -->
<a href="./page1.html">page1</a>
<a href="./page2.html">page2</a>
<div class="list-group">
<!-- 单页面路由跳转使用router-link标签 -->
<router-link to="/page1" class="list-group-item" active-class="active">page1</router-link>
<router-link to="/page2" class="list-group-item" active-class="active">page2</router-link>
</div>
<!-- 路由配置的组件显示区域 -->
<router-view></router-view>
使用多级路由/嵌套路由
- Page1.vue
<template>
<div>
<h1>Page1</h1>
<ul>
<li>
<!-- 嵌套路由,需要写出完整路径 -->
<router-link to="/page1/1">1</router-link>
</li>
<li>
<!-- 或使用命名路由,需要传对象 -->
<router-link :to="{name:'p1-2'}">2</router-link>
</li>
</ul>
<!-- 嵌套路由配置的子页面显示区域 -->
<router-view></router-view>
</div>
</template>
使用查询参数
- Page2.vue
<ul>
<li v-for="item in items" :key="item.id">
<!-- 带查询参数路由 -->
<!-- 传模板字符串 -->
<!-- <router-link :to="`/page2/details?id=${item.id}`">{{ item.id }}</router-link>-->
<!-- 传对象 -->
<router-link :to="{
path:'/page2/details',
query:{
id:item.id
}
}">
{{ item.id }}
</router-link>
</li>
</ul>
<!-- 嵌套路由配置的子页面显示区域 -->
<router-view></router-view>
- Page2_Details.vue
<template>
<!-- 从查询查询参数中取值 -->
<h3>Details {{ $route.query.id }}</h3>
</template>
使用路径参数
- Page1_2.vue
<h2>Page1-2</h2>
<div class="row">
<ul>
<li v-for="item in items" :key="item.id">
<!-- 路径参数路由 -->
<!-- <router-link :to="`/page1/2/details/${item.id}/${item.title}`">{{ item.title }}</router-link>-->
<!-- 必须使用命名路由 -->
<router-link :to="{
name:'p1-2-d',
params:{
id:item.id,
title:item.title
}
}">
{{ item.title }}
</router-link>
</li>
</ul>
</div>
<!-- 路由配置的组件显示区域 -->
<router-view></router-view>
- Page1_2_Details.vue
<!-- 从路径查询参数中取值 -->
<h3>Details {{ $route.params.title }}</h3>
<!-- 接受以props形式传入的参数 -->
<h3>{{ $id }}</h3>
组件属性传递
- 传递静态属性值
./router/index.js
{
path: '1',
component: Page1_1,
props: {myProp: 'hello'}
}
- 将所有路径参数以props形式传递给组件
./router/index.js
{
name:'p1-2-d',
path: 'details/:id/:title',
component: Page1_2_Details,
props: true
}
- 使用函数传递给组件属性(适用于查询参数)
./router/index.js
{
path: 'details',
component: Page2_Details,
// props($route) {
// return {id: $route.query.id, title: $route.query.title}
// },
// 使用解构赋值写法
// props({query}) {
// return {id: query.id, title: query.title}
// }
// 使用连续解构赋值写法
props({query: {id, title}}) {
return {id, title}
}
}
路由不记录导航历史
添加replace属性,导航时使用新地址替换当前导航历史记录,而不是压入历史记录栈
<router-link replace :to="`/page2/details?id=${item.id}`">{{ item.id }}
编程路由导航
// 导航并压入历史记录栈
this.$router.push({
name: 'p1-2-d',
query: {
id: 1,
title: '一'
}
})
// 导航并替换历史记录
this.$router.replace({})
// 前进(历史记录)
this.$router.back()
// 前进指定页数
this.$router.go(1)
// 返回(历史记录)
this.$router.forward()
// 返回指定页数
this.$router.go(-1)
缓存路由组件
路由跳转时默认将前一页的组件销毁,使用keep-alive标签包裹可以阻止销毁
<keep-alive include="可指定要缓存的组件名,其他组件不会被缓存">
<router-view></router-view>
</keep-alive>
<!-- 缓存多个组件 -->
<keep-alive :include="['Page1','Page2']">...
路由相关生命周期钩子
可用于激活/取消定时器等场景
activated() {
// 组件激活
},
deactivated() {
// 组件失活
}
路由守卫
./router/index.js
- 独享路由守卫
const routes = [
{
path: '/page1',
component: Page1,
// 路由元信息,可用于路由守卫处理
meta: {isAuth: true, title: 'Page1'},
// 独享路由守卫,路由前触发,没有独享后置守卫
beforeEnter: (to, from, next) => {
},
}
]
const router = new VueRouter({
routes: routes
})
- 全局前置路由守卫,每次地址切换前调用,初始化前调用,可用于鉴权等场景
router.beforeEach((to, from, next) => {
// to 目标路由, from 原路由
if (to.meta.isAuth === true) {
// 调用回调放行路由,否则不会跳转
next()
}
})
- 全局后置前置路由守卫,每次地址切换后调用,初始化后调用,可用于切换网页title等场景
router.afterEach((to, from) => {
document.title = to.meta.title || 'My Site'
})
组件路由守卫
- 通过路由规则进入组件时调用beforeRouteEnter
beforeRouteEnter(to, from, next) {
next()
}
- 通过路由规则离开组件时调用beforeRouteLeave
beforeRouteLeave(to, from, next) {
next()
}
- 执行顺序:组件路由离开->全局前置->独享->全局后置->组件路由进入
路由模式
- 默认hash模式,路由路径由#分隔
- history模式,路由路径么有#,兼容性不如hash
./router/index.js
new VueRouter({
mode: 'history'
})
注,history模式从根目录路由没有问题,在子页面刷新会导致404,因为会把路由路径当成资源路径向服务器请求页面,需要服务器端做相应配置
- nginx
location / {
try_files $uri $uri/ /index.html;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
2020-04-11 spring 启动时自动运行
2020-04-11 spring cloud oauth2授权服务 默认tokenService配置源码
2020-04-11 spring cloud 搭建oauth2授权服务 使用redis存储令牌
2020-04-11 spring cloud oauth2授权服务 clientDetails配置源码
2020-04-11 spring 验证框架
2020-04-11 IDEA 插件整理
2020-04-11 spring security笔记 默认登陆页面源码