实现SPA应用(单一页面,局部更新)前端路由(根据浏览器路径显示对应组件)
注意不屑@3会默认安装4版本,需要vue3
npm i vue-router@3
./router/index.js
import VueRouter from "vue-router";
// 路由配置,注意拼写
const routes = [];
// 创建并暴露router
export default new VueRouter({
routes
})
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>
<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>
<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>
<template>
<!-- 从查询查询参数中取值 -->
<h3>Details {{ $route.query.id }}</h3>
</template>
<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>
<!-- 从路径查询参数中取值 -->
<h3>Details {{ $route.params.title }}</h3>
<!-- 接受以props形式传入的参数 -->
<h3>{{ $id }}</h3>
{
path: '1',
component: Page1_1,
props: {myProp: 'hello'}
}
{
name:'p1-2-d',
path: 'details/:id/:title',
component: Page1_2_Details,
props: true
}
{
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()
}
})
router.afterEach((to, from) => {
document.title = to.meta.title || 'My Site'
})
beforeRouteEnter(to, from, next) {
next()
}
beforeRouteLeave(to, from, next) {
next()
}
new VueRouter({
mode: 'history'
})
注,history模式从根目录路由没有问题,在子页面刷新会导致404,因为会把路由路径当成资源路径向服务器请求页面,需要服务器端做相应配置
location / {
try_files $uri $uri/ /index.html;
}