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>