Vue3_15(VueRouter)
Vue Router https://router.vuejs.org/zh/guide/
vue-router是基于路由和组件的
路由用于设定访问路径, 将路径和组件映射起来.
在vue-router的单页面应用中, 页面的路径的改变就是组件的切换
使用vue-router
第一步:创建路由组件的组件;
第二步:配置路由映射: 组件和路径映射关系的routes数组;
第三步:通过createRouter创建路由对象,并且传入routes和history模式;
第四步:使用路由: 通过<router-link>和<router-view>;
例子:
router.js
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
// 配置映射关系
const routes = [
{
path: "/",
redirect: "/home"
},
// /home/shops
{
path: "/home",
name: "home",
component: () => import(/* webpackChunkName: "home-chunk" */"../pages/Home.vue"),
meta: {
name: "why",
age: 18,
height: 1.88
},
children: [
{
path: "",
redirect: "/home/message"
},
{
path: "message",
component: () => import("../pages/HomeMessage.vue")
},
{
path: "shops",
component: () => import("../pages/HomeShops.vue")
}
]
},
{
path: "/about",
name: "about",
component: () => import("../pages/About.vue")
},
{
path: "/user/:username/id/:id",
component: () => import("../pages/User.vue")
},
{
path: "/login",
component: () => import("../pages/Login.vue")
},
{
path: "/:pathMatch(.*)",
component: () => import("../pages/NotFound.vue")
}
];
// 创建一个路由对象router
const router = createRouter({
routes,
history: createWebHistory()
})
// 动态添加路由
const categoryRoute = {
path: "/category",
component: () => import("../pages/Category.vue")
}
// 添加顶级路由对象
router.addRoute(categoryRoute);
// 添加二级路由对象
router.addRoute("home", {
path: "moment",
component: () => import("../pages/HomeMoment.vue")
})
// 导航守卫beforeEach
let counter = 0;
// to: Route对象, 即将跳转到的Route对象
// from: Route对象,
/**
* 返回值问题:
* 1.false: 不进行导航
* 2.undefined或者不写返回值: 进行默认导航
* 3.字符串: 路径, 跳转到对应的路径中
* 4.对象: 类似于 router.push({path: "/login", query: ....})
*/
router.beforeEach((to, from) => {
console.log(`进行了${++counter}路由跳转`)
// if (to.path.indexOf("/home") !== -1) {
// return "/login"
// }
if (to.path !== "/login") {
const token = window.localStorage.getItem("token");
if (!token) {
return "/login"
}
}
})
export default router
App.vue
<template>
<div id="app">
<!-- props: href 跳转的链接 -->
<!-- props: route对象 -->
<!-- props: navigate导航函数 -->
<!-- props: isActive 是否当前处于活跃的状态 -->
<!-- props: isExactActive 是否当前处于精确的活跃状态 -->
<router-link to="/home" v-slot="props" custom>
<button @click="props.navigate">{{props.href}}</button>
<button @click="props.navigate">哈哈哈</button>
<span :class="{'active': props.isActive}">{{props.isActive}}</span>
<span :class="{'active': props.isActive}">{{props.isExactActive}}</span>
<!-- <p>{{props.route}}</p> -->
</router-link>
<router-link to="/about">关于</router-link>
<router-link to="/user/kobe/id/111">用户</router-link>
<router-link to="/category">分类</router-link>
<button @click="jumpToAbout">关于</button>
<button @click="forwardOneStep">前进一步</button>
<router-view v-slot="props">
<!-- <transition name="why"> -->
<keep-alive>
<component :is="props.Component"></component>
</keep-alive>
<!-- </transition> -->
</router-view>
</div>
</template>
<script>
import { useRouter } from 'vue-router'
import NavBar from './components/NavBar.vue'
export default {
name: 'App',
components: {
NavBar
},
methods: {
// jumpToAbout() {
// // router
// this.$router.push("/about")
// }
},
setup() {
const router = useRouter();
const jumpToAbout = () => {
// router.push("/about")
// router.push({
// path: "/about",
// query: {
// name: "why",
// age: 18
// }
// })
// router.replace("/about")
}
const forwardOneStep = () => {
router.go(1)
// router.go(-1)
// router.forward()
// router.back()
}
return {
jumpToAbout,
forwardOneStep
}
}
}
</script>
<style>
.why-active {
color: red;
}
.why-enter-from,
.why-leave-to {
opacity: 0;
}
.why-enter-active,
.why-leave-active {
transition: opacity 1s ease;
}
</style>
前端路由是如何做到URL和内容进行映射呢?监听URL的改变。
URL的hash
URL的hash也就是锚点(#), 本质上是改变window.location的href属性;
可以通过直接赋值location.hash来改变href, 但是页面不发生刷新;
<div id="app">
<a href="#/home">home</a>
<a href="#/about">about</a>
<div class="content">Default</div>
</div>
<script>
const contentEl = document.querySelector('.content');
window.addEventListener("hashchange", () => {
switch(location.hash) {
case "#/home":
contentEl.innerHTML = "Home";
break;
case "#/about":
contentEl.innerHTML = "About";
break;
default:
contentEl.innerHTML = "Default";
}
})
</script>
HTML5的History
replaceState:替换原来的路径;
pushState:使用新的路径;
popState:路径的回退;
go:向前或向后改变路径;
forward:向前改变路径;
back:向后改变路径;
<div id="app">
<a href="/home">home</a>
<a href="/about">about</a>
<div class="content">Default</div>
</div>
<script>
const contentEl = document.querySelector('.content');
const changeContent = () => {
switch(location.pathname) {
case "/home":
contentEl.innerHTML = "Home";
break;
case "/about":
contentEl.innerHTML = "About";
break;
default:
contentEl.innerHTML = "Default";
}
}
const aEls = document.getElementsByTagName("a");
for (let aEl of aEls) {
aEl.addEventListener("click", e => {
e.preventDefault();
const href = aEl.getAttribute("href");
history.pushState({}, "", href);
//history.replaceState({}, "", href);
changeContent();
})
}
window.addEventListener("popstate", changeContent)
</script>

浙公网安备 33010602011771号