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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | <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, 但是页面不发生刷新;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <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:向后改变路径;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <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> |
分类:
Vue
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!