- 加载vue-router
yarn add vue-router
- main中引入
import Vue from "vue";
import App from "./App.vue";
import store from "@/store";
import VueRouter from "vue-router";
import router from "@/router";
Vue.use(VueRouter);
Vue.config.productionTip = false;
new Vue({
store,
router,
render: (h) => h(App),
}).$mount("#app");
- router下index.js中进行路由配置
- 嵌套路由时子路由底层遍历会自动加“/”,所以children中不加,自动拼接成" /helloWorldCopy/news"
import VueRouter from "vue-router";
import HelloWorld from "@/components/HelloWorld.vue";
import HelloWorldCopy from "@/components/HelloWorld.vue";
import News from "@/components/News.vue";
export default new VueRouter({
routes: [
{
path: "/helloWorld",
component: HelloWorld,
},
{
path: "/helloWorldCopy",
component: HelloWorldCopy,
children: [
{
path: "news",
component: News,
},
],
},
],
});
- router-link的query参数
<template>
<div>
<div>
<!-- 常规写法 -->
<router-link :to="`/helloWorldCopy?msg=${1}&title=${title}`">
<span>哈哈哈</span>
</router-link>
<!-- 对象写法 -->
<router-link
:to="{
path: '/helloWorldCopy',
query: {
msg: 1,
title,
},
}"
>
<span>哈哈哈</span>
</router-link>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
title: "hh",
};
},
};
</script>
- 命名路由
<router-link
:to="{
name: 'helloWorldCopy',
query: {
msg: 1,
title,
},
}"
>
<span>哈哈哈</span>
</router-link>
- params参数
- params不允许在router-link中写path路径,只能写name
<template>
<div>
<div>
<!-- 常规写法 -->
<router-link :to="`/helloWorldTest/${1}/${title}`">
<span>哈哈哈</span>
</router-link>
<!-- params错误写法 -->
<router-link
:to="{
path: '/helloWorldTest',
params: {
id: 1,
title,
},
}"
>
<span>哈哈哈</span>
</router-link>
<router-link
:to="{
name: 'helloWorldTest',
params: {
id: 1,
title,
},
}"
>
<span>哈哈哈</span>
</router-link>
</div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
title: "hh",
};
},
};
</script>
-
路由props写法,避免代码冗余
-
第一种:props对象写法,可惜只能写固定常量值,作为props传递给当前组件
//before
<div>
<span>{{ $route.params.id }}</span>
<span>{{ $route.params.title }}</span>
</div>
//after
//router中
{
name: "helloWorldTest",
path: "/helloWorldTest/:id/:title",
component: HelloWorldTest,
//props第一种写法,对象写法
props: {
a: 2,
title: "嘻嘻",
},
},
//HelloWorldTest组件中
<template>
<div>
<span>{{ $route.params.id }}</span>
<span>{{ $route.params.title }}</span>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: ["a", "title"],
data() {
return {};
},
mounted() {
console.log(this.$route);
console.log(this.a); //2
console.log(this.title); //嘻嘻
},
};
</script>
- 第二种布尔值写法,会将所接收到的参数通过props进行传递,缺点是只支持params参数,不支持query,有局限性
{
name: "helloWorldTest",
path: "/helloWorldTest/:id/:title",
component: HelloWorldTest,
//props第一种写法,对象写法
// props: {
// a: 2,
// title: "嘻嘻",
// },
//props第二种写法,布尔类型,
props: true,
},
<template>
<div>
<span>{{ $route.params.id }}</span>
<span>{{ $route.params.title }}</span>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: ["id", "title"],
data() {
return {};
},
mounted() {
console.log(this.$route);
console.log(this.id); //1
console.log(this.title); //哈哈
},
};
</script>
- 第三种props写法,值为函数,VueRouter会在props函数中将$route作为形参提供给你,我们可以通过解构赋值,简洁代码
{
name: "helloWorldTest",
path: "/helloWorldTest/:id/:title",
component: HelloWorldTest,
// props第一种写法,对象写法
// props: {
// a: 2,
// title: "嘻嘻",
// },
// props第二种写法,布尔类型,
// props:true,
// props第三种写法,函数类型,
// props($route) {
// console.log($route);
// return {
// id: $route.params.id,
// title: $route.params.title,
// };
// },
props({ params: { id, title } }) {
return {
id: id,
title: title,
};
},
},
-
注意下keep-alive include="[组件名]"
-
路由守卫(全局前置,全局后置,独享)
import VueRouter from "vue-router";
import HelloWorld from "@/components/HelloWorld.vue";
import HelloWorldCopy from "@/components/HelloWorldCopy.vue";
import HelloWorldTest from "@/components/HelloWorldTest.vue";
import News from "@/components/News.vue";
const router = new VueRouter({
routes: [
{
name: "helloWorld",
path: "/helloWorld",
component: HelloWorld,
meta: {
isAuth: true,
},
//独享路由守卫(全局前置守卫先执行)
beforeEnter(to, form, next) {
console.log(to, form);
next();
},
},
{
name: "helloWorldTest",
path: "/helloWorldTest/:id/:title",
component: HelloWorldTest,
meta: {
isAuth: false,
},
},
{
name: "helloWorldCopy",
path: "/helloWorldCopy",
component: HelloWorldCopy,
children: [
{
name: "news",
path: "news",
component: News,
},
],
},
],
});
//全局前置守卫 可用于权限控制 路由切换前调用与初始化被调用
router.beforeEach((to, from, next) => {
if (to.meta.isAuth) {
next();
}
});
//全局后置守卫 路由切换后调用与初始化被调用
router.afterEach((to, from) => {
// console.log(to, from);
});
export default router;
- 组件内路由守卫(进入或离开,通过路由规则,进入/离开该组件调用)
<template>
<div>
<router-link :to="`/helloWorldTest/${1}/${title}`">
<span>哈哈哈</span>
</router-link>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
title: "hh",
};
},
beforeRouteEnter(to, from, next) {
console.log("组件进入");
console.log(to);
if (to.meta.isAuth) {
next();
}
},
beforeRouteLeave(to, from, next) {
console.log("组件离开");
next();
},
};
</script>
全部打开他们的执行顺序如下: