基本使用
安装
npm i vue-router
配置
./router/index.js
import VueRouter from "vue-router";
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 VueRouter from "vue-router";
import router from "./router";
Vue.config.productionTip = false;
Vue.use(VueRouter);
new Vue({
render: (h) => h(App),
router: router,
}).$mount("#app");
使用
<template>
<div id="app">
<router-link to="/about" class="router-link" active-class="active">about</router-link>
<router-link to="/home" class="router-link" active-class="active">home</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "App",
components: {},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.router-link {
margin: 2rem;
transition: all 0.2s;
}
.active {
font-size: larger;
}
</style>
几个注意点
- 一般的,我们将路由组件放在./pages/目录下,而./components/目录下只放静态组件路由切换
- 路由切换时,其他非路由选中的页面被销毁
- 每个组件都有
$route
属性,存储自己的路由信息 - 整个应用只有一个 router,可以通过组件的
$router
属性获取 - /可以理解为根目录下路由,使用 to 的时候要加/
多级路由
配置
import VueRouter from "vue-router";
import About from "../pages/About";
import Home from "../pages/Home";
import InnerA from "../pages/InnerA";
import InnerB from "../pages/InnerB";
export default new VueRouter({
routes: [
{
path: "/about",
component: About,
},
{
path: "/home",
component: Home,
children: [
{ path: "ia", component: InnerA },
{ path: "ib", component: InnerB },
],
},
],
});
使用
<template>
<div>
<h2>homepage</h2>
<router-link to="/home/ia" class="router-link" active-class="active">linkA</router-link>
<router-link to="/home/ib" class="router-link" active-class="active">linkB</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "a-Home",
};
</script>
<style scoped>
.router-link {
margin: 2rem;
transition: all 0.2s ease-in-out;
font-size: 1rem;
}
.active {
font-size: 2rem;
}
</style>
注意
- 在上级(一级)路由添加
children
配置项,里面的子路由配置path
不需要加/
- 使用的时候,
to
属性内容需要跟上父级路由,可以理解为从根目录下路由开始
命名路由
目的:简化跳转书写
当路由路径较长时,可以给特定路由一个 name
,然后使用 router-link
时可以通过name
跳转
export default new VueRouter({
routes: [
{
path: "/about",
component: About,
},
{
path: "/home",
component: Home,
children: [
{
path: "ia",
component: InnerA,
children: [{ path: "msg", component: Msg, name: "msg" }],//here
},
{
path: "ib",
component: InnerB,
},
],
},
],
});
路由传参 query
对象配置传参
:to="{
name: 'msg',
query: {
id: msg.id,
item: msg.title,
},
}"
接收参数
computed: {
id() {
return this.$route.query.id;
},
title() {
return this.$route.query.item;
},
},
路由传参 params
配置占位符
{
path: "ia",
component: InnerA,
children: [{ path: "msg/:id/:item", component: Msg ,name:'msg'}],
},
传参
字符串写法
:to="`/home/ia/msg/${msg.id}/${msg.title}`"
对象写法
:to="{
name: 'msg',
params: {
id: msg.id,
item: msg.title,
},
}"
使用 params 传参时,不能使用 path,只能使用 name
接收
id() {
return this.$route.params.id;
},
title() {
return this.$route.params.item;
},
两种传参区别
- query 方式生成的 url 为/xx?id=id,params 方式生成的 url 为 xx/id
- path 只能使用 query 方式
- params 方式需要注意的是需要定义路由信息如:path: '/xx/:id',这样才能进行携带参数跳转,否则 url 不会进行变化,并且再次刷新页面后参数会读取不到
- router-link 是 v-for 渲染的情况下,使用 params 参数可以让 active-class 生效,因为这个选项是根据路由地址来计算的,在 query 情况下地址不变,只变参数,会出现渲染的 link 全部 active
配置 props
配置
//props写法1,key-value以props形式传给Msg,传递固定数据,很少用
props: { a: 1, b: "hello" },
//props写法2,值为布尔值,若为真,就会把该路由组件收到的所有params参数以props参数传给组件Msg,但不会理会query参数
props: true,
//props写法3,值为函数,把所有query参数传递给Msg,用解构更简洁,个人感觉作用鸡肋
props({ query: { id, item } }) {
return { id, item };
},
使用
<template>
<div>
<h2>{{ id }} {{ item }}</h2>
</div>
</template>
<script>
export default {
name: "a-msg",
mounted() {
console.log(this.$route);
},
computed: {},
props: ["id", "item"],
};
</script>
<style>
</style>
router-link replace
作用:控制路由跳转时操作浏览器历史记录的模式
浏览器的历史记录有两种写入方式,分别为 push 和 replace。push 是追加记录(默认),可以按步骤一步步后退;replace 是替换当前记录,后退时不再一步步后退,而是回退到上一个 push 内容里
开启 replace 模式,在 router-link 标签内添加replace
或者:replace:"true"
编程式路由跳转
不借助 router-link 实现路由跳转
pushShow() {
this.$router.push({
name: "msg",
params: {
id: xxx,
item: xxx,
},
});
},
replaceShow() {
this.$router.replace({
name: "msg",
params: {
id: xxx,
item: xxx,
},
});
},
forward() {
this.$router.forward();
},
back() {
this.$router.back();
},
refresh() {
this.$router.go(0);
},
keep-alive
让 router-view 切换时做缓存,不销毁切换出去的页面
<keep-alive include="">
<router-view></router-view>
</keep-alive>
include 不写就是全缓存,如果需要指定缓存组件,则写入组件名或组件名数组
路由守卫
全局守卫
const router = new VueRouter({
routes: [
{
name: "about",
path: "/about",
component: About,
meta: {
title: "关于",
isAuth:true
},
},
...
],
});
//全局前置路由守卫——初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to, from, next) => {
console.log(to, from);
//to.path === "/home/ia" || to.path === "/home/ib"
if (to.meta.isAuth) { //鉴权
if (localStorage.getItem("keyword") === "haian") {
next();
} else {
console.log(localStorage.getItem("keyword"));
alert("not haian");
}
} else {
next();
}
});
//全局后置路由守卫——初始化时执行、每次路由切换后执行
router.afterEach((to, from) => {
console.log(to, from);
document.title = to.meta.title;
});
export default router;
独享路由守卫
{
name: "innera",
path: "ia",
component: InnerA,
meta: {
isAuth: true,
title: "内页 A",
},
beforeEnter: (to, from, next) => {
console.log(to,from)
if (localStorage.getItem("keyword") === "haian") {
next();
} else {
console.log(localStorage.getItem("keyword"));
alert("not haian");
}
},
children: [
{
...
},
],
},
在路由配置加beforeEnter
,用法同全局路由守卫,但是独享路由守卫没有后置的
组件内守卫
export default {
name: "a-Home",
beforeRouteEnter(to, from, next) {
// 通过路由规则,进入该组件时被调用
console.log(to, from);
if (localStorage.getItem("keyword") === "haian") {
next();
} else {
console.log(localStorage.getItem("keyword"));
alert("not haian");
}
},
beforeRouteLeave(to, from, next) {
// 通过路由规则,离开该组件时被调用
console.log(to, from, next);
alert("goodbye ~");
next();
},
};
</script>
注意,这两个钩子只有根据路由规则进入、离开时才会被调用
history 与 hash 模式
关于 hash
默认模式为 hash,对一个 url 来说,hash 就是#及其后面的值。
hash 值不会包含在 http 请求中,hash 值不会带给服务器
开启 history 模式
const router = new VueRouter({
mode:'history',
routes: []
...
区别
hash 模式:
- 地址中永远带着#,不美观
- 若以后将地址通过第三方手机 app 分享,若 app 校验严格,则地址会标记为不合法
- 兼容性较好
history 模式:
- 地址干净美观
- 兼容性略差
- 应用部署上线时,需要后端人员支持,解决刷新页面 404 问题