现在如果使用 npm 安装 vue-router 默认为 vue-router4
vue-router4
适配 Vue3
,vue-router3
适配 Vue2
npm i vue-router@3
创建 router/index.js
文件
import Vue from "vue";
import VueRouter from "vue-router";
// 使用插件,使用路由不分前后
Vue.use(VueRouter)
// 导入路由组件
import About from "../components/About"
import Home from "../components/Home"
// 创建路由并导出
export default new VueRouter({
routes: [
{
// 路由对应的路径
path: "/about",
// 对应路径展示的组件
component: About
},
{
path: "/home",
component: Home
}
]
})
import Vue from 'vue'
import App from './App.vue'
// 导入路径配置
import router from "./router/index"
Vue.config.productionTip = false
new Vue({
render: h => h(App),
// 挂载路由
router
}).$mount('#app')
// 挂载之后会多两个属性
// $route:每个组件独享的属性
// $router:全局的一个属性
<router-link active-class="active" to="/about">点我显示about组件router-link>
<router-link active-class="active" to="/home">点我显示home组件router-link>
<router-view>router-view>
注意:
在对路由组件进行切换时,组件会进行创建和销毁
路由组件通常存放在
pages
文件夹,一般组件通常存放在components
文件夹
export default new VueRouter({
routes: [
{
path: "/about",
component: About,
// msg1 和 msg2 为 about 的二级路由
children: [
{
// 一级路由 path 需要加 /,二级路由不需要
path: "news",
component: News
},
{
path: "msg",
component: Msg
}
]
},
{
path: "/home",
component: Home
}
]
})
<h2>我是About组件h2>
<router-link active-class="active" to="/about/news">显示Newsrouter-link>
<router-link active-class="active" to="/about/msg">显示Msgrouter-link>
<router-view>router-view>
query参数
<router-link :to="`/about/msg/detail?id=${item.id}&title=${item.title}`">
{{ item.title }}
router-link>
<router-link
:to="{
path: '/about/msg/detail',
query: {
id: item.id,
title: item.title,
},
}"
>{{ item.title }}router-link>
<router-view>router-view>
params参数
// params 需要路由路径配合
{
name: "Demo"
path: '/demo/:id/:title',
component: Demo,
}
<router-link :to="`/demo/${item.id}/${item.title}`">
{{ item.title }}
router-link>
<router-link
:to="{
name: 'Demo',
params: {
id: item.id,
title: item.title,
},
}"
>{{ item.title }}router-link>
注意:params 传参,使用 to 的对象写法,不能使用 path 配置项,必须使用 name 配置
添加 name 属性,可以简化路由跳转
{
path: '/demo',
component: Demo,
children: [
{
path: 'test',
component: Test,
children: [
{
name: 'hello' // 给路由命名
path: 'welcome',
component: Hello,
}
]
}
]
}
<router-link to="/demo/test/welcome">跳转router-link>
<router-link :to="{name:'hello'}">跳转router-link>
<router-link
:to="{
name: 'hello',
query: {
id: 666,
title: '你好'
}
}"
>跳转router-link>
定义路由的时候可以配置 meta
字段:也就是自定义属性
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
meta: {
requiresAuth: true
}
}
]
}
]
})
// 传参时的配置
{
name: "Demo"
path: '/demo',
component: Demo,
// 对象式,这种方式只能传入静态数据
props: {flag: true}
// 布尔值,把 params 的参数传递给 Demo 组件,只能操作 params 参数
props: true
// 函数式,这种方式都可以传递,比就好的一种方式
props($router) {
return {
id: $router.query.id,
title: $router.query.title,
}
}
}
// 这里配置项的写法和组件 props 属性是一样的
// 不用担心会重复,因为路由组件是不能通过组件标签名去使用
props: {
id: String,
title: String,
}
不借助
进行路由跳转
// 向浏览器中追加一个历史记录
this.$router.push({
// 跳转路径
// 携带参数
})
// 替换当前历史记录
this.$router.replace({
// 跳转路径
// 携带参数
})
// 对浏览器路由历史记录进行操作
// 回退
this.$router.back()
// 前进
this.$router.forward()
// n 正多少就前进多少,n 负多少就后退多少
this.$router.go(n)
在路由组件进行切换时,组件经过创建销毁
使用
包裹住的路由组件,创建一次后不会在销毁了,也就是缓存
<keep-alive include="news">
<router-view>router-view>
keep-alive>
使用
才会触发的两个生命周期钩子
activated(){
console.log("激活时触发,显示该组件时触发")
}
deactivated(){
console.log("失活时触发,离开该组件时触发")
}
{
fullPath: "路由路径,会包含 query 和 params 参数",
path: "路由路径,只会包含 params 参数",
name: "路由命名",
hash: "路由模式",
matched: [
// 包含当前路由的所有嵌套路径片段的路由记录,包括父子
],
meta: {
// 路由元信息
},
params: "参数",
query: "参数"
}
//全局前置守卫:初始化时执行、每次路由切换前执行
router.beforeEach((to, from, next) => {
// to:进入哪个路由,配置
// from:从哪个路由来,配置
// next:放行,如果不放行路由将会被拦截
// next 括号中也可以添加跳转路由路径,next('/')、next({path: '/'})、next({name: '/'})
})
//全局后置守卫:初始化时执行、每次路由切换后执行
router.afterEach((to, from) => {
// 后置路由没有 next,都跳完了还怎么拦
})
// 独享直接写在路由配置项中
{
name: "xxx",
path:"xxx/xxx",
component: Xxx,
beforeEnter(to,from,next){ }
}
// 组件内的守卫,要写在组件中
export default {
//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) { },
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) { }
}
beforeRouteLeave
守卫。beforeEach
守卫。beforeRouteUpdate
守卫 (2.2+)。beforeEnter
。beforeRouteEnter
。beforeResolve
守卫 (2.5+)。afterEach
钩子。beforeRouteEnter
守卫中传给 next
的回调函数,创建好的组件实例会作为回调函数的参数传入。对于一个 url 来说,# 及其后面的内容就是 hash 值
hash 值不会包含在 HTTP 请求中,hash 值不会带给服务器,也不会发送请求,这就是单页面的原理
hash 模式:
history 模式:
设置两种模式
const router = new VueRouter({
mode: "history/hash"
})
node 解决 history 模式刷新页面404
const express = require("express")
const history = require("connect-history-api-fallback")
const app = express()
app.use(history())
因为 Vue 是单页面应用,就导致了第一次进入页面的时候,会加载很久
可以给路由组件进行懒加载,这样只有访问该组件的时候才会加载
// 写法
{
name: "Demo"
path: '/demo/:id/:title',
component: () => import('./Foo.vue')
}
// 当访问根路径时,重定向到 home 页
export default new VueRouter({
routes:[
{
path: "/",
redirect: "/home"
},
]
})
// 给路由起别名
export default new VueRouter({
routes:[
{
path: "/home",
alias: "/haha",
component: Home
},
]
})
<router-link to="/haha">router-link>