Vue(六)
1. 前端路由
hash值代表url地址中#号后面的内容,
不同的hash地址对应不同的组件

1.2 简易路由
| <template> |
| <div class="app-container"> |
| <h1>App 根组件</h1> |
| |
| <!-- 定义hash值 #号后面的内容 --> |
| <a href="#/home">首页</a> |
| <a href="#/movie">电影</a> |
| <a href="#/about">关于</a> |
| <hr /> |
| |
| <!-- 根据hash值与组件的关系,按需展示组件 --> |
| <component :is="comName"></component> |
| </div> |
| </template> |
| |
| <script> |
| // 导入组件 |
| import Home from '@/components/Home.vue' |
| import Movie from '@/components/Movie.vue' |
| import About from '@/components/About.vue' |
| |
| export default { |
| name: 'App', |
| |
| data(){ |
| return { |
| comName:'Home' |
| } |
| }, |
| // 注册组件 |
| components: { |
| Home, |
| Movie, |
| About |
| }, |
| |
| // 在组件被创建的时候,绑定hash值是否变化 |
| |
| created(){ |
| window.onhashchange=() => { |
| |
| // 根据hash值的不同按需展示组件 |
| if(location.hash==='#/home'){ |
| this.comName='Home' |
| }else if(location.hash==='#/movie'){ |
| this.comName='Movie' |
| }else if(location.hash==='#/about'){ |
| this.comName='About' |
| } |
| } |
| } |
| } |
| </script> |
| |
| <style lang="less" scoped> |
| .app-container { |
| background-color: #efefef; |
| overflow: hidden; |
| margin: 10px; |
| padding: 15px; |
| > a { |
| margin-right: 10px; |
| } |
| } |
| </style> |
| |

1.3 使用vue的官方路由
- 安装vue-router包
| npm i vue-router@3.5.2 -S |
- 创建路由模块(src/router/index.js)
| |
| |
| import Vue from 'vue' |
| import VueRouter from 'vue-router' |
| |
| |
| |
| Vue.use(VueRouter) |
| |
| |
| |
| const router =new VueRouter() |
| |
| |
| |
| export default router |
| import Vue from 'vue' |
| import App from './App2.vue' |
| |
| |
| import 'bootstrap/dist/css/bootstrap.min.css' |
| |
| import '@/assets/global.css' |
| |
| |
| |
| import router from "@/router" |
| |
| Vue.config.productionTip = false |
| |
| new Vue({ |
| render: h => h(App), |
| |
| |
| router |
| }).$mount('#app') |
| |
1.4 一个路由案例
| <template> |
| <div class="app-container"> |
| <h1>App2 组件</h1> |
| |
| <!-- 定义链接,hash值 --> |
| |
| <!-- 使用router-link代替a链接 --> |
| |
| <router-link to="/home">首页</router-link> |
| <router-link to="/movie">电影</router-link> |
| <router-link to="/about">关于</router-link> |
| |
| <!-- <a href="#/home">首页</a> |
| <a href="#/movie">电影</a> |
| <a href="#/about">关于</a> --> |
| <hr /> |
| |
| <!-- 定义路由占位符,代表将要被渲染的组件 --> |
| <router-view></router-view> |
| |
| <!-- 在router/index.js文件中配置路由对应关系 --> |
| </div> |
| </template> |
| |
| <script> |
| export default { |
| name: 'App' |
| } |
| </script> |
| |
| <style lang="less" scoped> |
| .app-container { |
| background-color: #efefef; |
| overflow: hidden; |
| margin: 10px; |
| padding: 15px; |
| > a { |
| margin-right: 10px; |
| } |
| } |
| </style> |
| |
| |
| |
| import Vue from "vue" |
| import VueRouter from "vue-router" |
| |
| |
| |
| import Home from "@/components/Home.vue" |
| import Movie from "@/components/Movie.vue" |
| import About from "@/components/About.vue" |
| |
| |
| |
| Vue.use(VueRouter) |
| |
| |
| |
| const router = new VueRouter({ |
| |
| routes: [ |
| { path: "/home", component: Home }, |
| { path: "/about", component: About }, |
| { path: "/movie", component: Movie } |
| ] |
| }) |
| |
| |
| |
| export default router |
| |
1.5 路由重定向
| const router = new VueRouter({ |
| |
| routes: [ |
| |
| { path: "/", redirect: "/home" }, |
| { path: "/home", component: Home }, |
| { path: "/about", component: About }, |
| { path: "/movie", component: Movie } |
| ] |
| }) |
1.6 子路由嵌套
| <template> |
| <div class="about-container"> |
| <h3>About 组件</h3> |
| <!-- 嵌套子路由 --> |
| |
| <router-link to="/about/tab1">tab1</router-link> |
| <router-link to="/about/tab2">tab2</router-link> |
| |
| <!-- 路由占位符 --> |
| <router-view></router-view> |
| </div> |
| </template> |
| |
| <script> |
| |
| |
| export default { |
| name: 'About' |
| } |
| </script> |
| |
| <style lang="less" scoped> |
| .about-container { |
| min-height: 200px; |
| background-color: skyblue; |
| padding: 15px; |
| > a { |
| margin-right: 10px; |
| } |
| } |
| </style> |
| |
| |
| |
| import Vue from "vue" |
| import VueRouter from "vue-router" |
| |
| |
| |
| import Home from "@/components/Home.vue" |
| import Movie from "@/components/Movie.vue" |
| import About from "@/components/About.vue" |
| import Tab1 from '@/components/tabs/Tab1.vue' |
| import Tab2 from '@/components/tabs/Tab2.vue' |
| |
| |
| |
| Vue.use(VueRouter) |
| |
| |
| |
| const router = new VueRouter({ |
| |
| routes: [ |
| |
| { path: "/", redirect: "/home" }, |
| { path: "/home", component: Home }, |
| |
| { |
| path: "/about", |
| component: About, |
| redirect: "/about/tab1", |
| children: [ |
| { path: "tab1", component: Tab1 }, |
| { path: "tab2", component: Tab2 } |
| ] |
| }, |
| { path: "/movie", component: Movie } |
| ] |
| }) |
| |
| |
| |
| export default router |
| |
路由的children属性(一个数组)来定义子路由,子路由的path不用添加"/",子路由可以是在父路由的基础上写路径

1.7 默认子路由
- 进入父路由时,直接进入默认子路由,而不需要使用重定向
- path的路径为空
| |
| |
| import Vue from "vue" |
| import VueRouter from "vue-router" |
| |
| |
| |
| import Home from "@/components/Home.vue" |
| import Movie from "@/components/Movie.vue" |
| import About from "@/components/About.vue" |
| import Tab1 from '@/components/tabs/Tab1.vue' |
| import Tab2 from '@/components/tabs/Tab2.vue' |
| |
| |
| |
| Vue.use(VueRouter) |
| |
| |
| |
| const router = new VueRouter({ |
| |
| routes: [ |
| |
| { path: "/", redirect: "/home" }, |
| { path: "/home", component: Home }, |
| |
| { |
| path: "/about", |
| component: About, |
| |
| children: [ |
| |
| {path:"",component:Tab1}, |
| { path: "tab1", component: Tab1 }, |
| { path: "tab2", component: Tab2 } |
| ] |
| }, |
| { path: "/movie", component: Movie } |
| ] |
| }) |
| |
| |
| |
| export default router |
| |
1.8 动态路由
-
提高路由的复用性
-
路由地址不同,但使用的是同一个组件
-
app2
| <template> |
| <div class="app-container"> |
| <h1>App2 组件</h1> |
| |
| <!-- 定义链接,hash值 --> |
| |
| <!-- 使用router-link代替a链接 --> |
| |
| <router-link to="/home">首页</router-link> |
| <!-- <router-link to="/movie">电影</router-link> --> |
| <!-- 根据不同的id,获取不同的电影详情页 --> |
| <router-link to="/movie/1">电影1</router-link> |
| <router-link to="/movie/2">电影2</router-link> |
| <router-link to="/movie/3">电影3</router-link> |
| <router-link to="/about">关于</router-link> |
| |
| <!-- <a href="#/home">首页</a> |
| <a href="#/movie">电影</a> |
| <a href="#/about">关于</a> --> |
| <hr /> |
| |
| <!-- 定义路由占位符,代表将要被渲染的组件 --> |
| <router-view></router-view> |
| |
| <!-- 在router/index.js文件中配置路由对应关系 --> |
| </div> |
| </template> |
| |
| <script> |
| export default { |
| name: 'App' |
| } |
| </script> |
| |
| <style lang="less" scoped> |
| .app-container { |
| background-color: #efefef; |
| overflow: hidden; |
| margin: 10px; |
| padding: 15px; |
| > a { |
| margin-right: 10px; |
| } |
| } |
| </style> |
| |
| <template> |
| <div class="movie-container"> |
| <!-- 路由对象 this.$route --> |
| <h3>Movie 组件-----电影{{this.$route.params.mid}}</h3> |
| <button @click="getmovie">获取电影信息</button> |
| </div> |
| </template> |
| |
| <script> |
| export default { |
| name: 'Movie', |
| |
| methods: { |
| getmovie(){ |
| console.log(this); |
| } |
| } |
| } |
| </script> |
| |
| <style lang="less" scoped> |
| .movie-container { |
| min-height: 200px; |
| background-color: lightsalmon; |
| padding: 15px; |
| } |
| </style> |
| |
| |
| { path: "/movie/:mid", component: Movie } |

1.9 动态路由接收参数的第二种方式
| |
| |
| { path: "/movie/:mid", component: Movie ,props:true} |
| props:{ |
| mid:{ |
| type:String |
| } |
| }, |
1.10 路径参数和查询参数

| <template> |
| <div class="app-container"> |
| <h1>App2 组件</h1> |
| |
| <!-- 定义链接,hash值 --> |
| |
| <!-- 使用router-link代替a链接 --> |
| |
| <router-link to="/home">首页</router-link> |
| <!-- <router-link to="/movie">电影</router-link> --> |
| <!-- 根据不同的id,获取不同的电影详情页 --> |
| |
| <!-- 路径参数:hash后面/后面的内容 --> |
| <!-- 查询参数:hash后面?后面的内容 --> |
| <router-link to="/movie/1">电影1</router-link> |
| <router-link to="/movie/2?name=zs&age=18">电影2</router-link> |
| <router-link to="/movie/3">电影3</router-link> |
| <router-link to="/about">关于</router-link> |
| |
| <!-- <a href="#/home">首页</a> |
| <a href="#/movie">电影</a> |
| <a href="#/about">关于</a> --> |
| <hr /> |
| |
| <!-- 定义路由占位符,代表将要被渲染的组件 --> |
| <router-view></router-view> |
| |
| <!-- 在router/index.js文件中配置路由对应关系 --> |
| </div> |
| </template> |
| |
| <script> |
| export default { |
| name: "App" |
| } |
| </script> |
| |
| <style lang="less" scoped> |
| .app-container { |
| background-color: #efefef; |
| overflow: hidden; |
| margin: 10px; |
| padding: 15px; |
| > a { |
| margin-right: 10px; |
| } |
| } |
| </style> |
| |

2. 路由导航
点击链接进行跳转,a链接,router-link链接
调用api方法实现跳转,如location.href属性的修改
2.2 vue-router提供的导航api


实例
| <template> |
| <div class="home-container"> |
| <h3>Home 组件</h3> |
| <!-- 定义button按钮,实现跳转到电影1 --> |
| <button @click="gotoMovie1">跳转到电影1</button> |
| </div> |
| </template> |
| |
| <script> |
| export default { |
| name: 'Home', |
| methods: { |
| gotoMovie1(){ |
| // 通过push方法跳转页面,存在历史记录 |
| // this.$router.push('/movie/1'); |
| // 通过replace方法跳转页面,无历史记录 |
| this.$router.replace('movie/1'); |
| } |
| } |
| } |
| </script> |
| |
| <style lang="less" scoped> |
| .home-container { |
| min-height: 200px; |
| background-color: pink; |
| padding: 15px; |
| } |
| </style> |
| |
2.3 导航守卫

2.4 全局前置守卫
| |
| |
| import Vue from "vue" |
| import VueRouter from "vue-router" |
| |
| |
| |
| import Home from "@/components/Home.vue" |
| import Movie from "@/components/Movie.vue" |
| import About from "@/components/About.vue" |
| import Tab1 from '@/components/tabs/Tab1.vue' |
| import Tab2 from '@/components/tabs/Tab2.vue' |
| |
| |
| |
| Vue.use(VueRouter) |
| |
| |
| |
| const router = new VueRouter({ |
| |
| routes: [ |
| |
| { path: "/", redirect: "/home" }, |
| { path: "/home", component: Home }, |
| |
| { |
| path: "/about", |
| component: About, |
| |
| children: [ |
| |
| {path:"",component:Tab1}, |
| { path: "tab1", component: Tab1 }, |
| { path: "tab2", component: Tab2 } |
| ] |
| }, |
| |
| |
| |
| { path: "/movie/:mid", component: Movie ,props:true} |
| ] |
| }) |
| |
| |
| |
| |
| |
| |
| router.beforeEach((to,from,next)=>{ |
| |
| next() |
| console.log(from); |
| console.log('---------------------'); |
| console.log(to); |
| }) |
| |
| |
| |
| export default router |
| |

2.5 根据情况控制权限

2.6 控制后台主页的访问权限
| router.beforeEach((to,from,next)=>{ |
| |
| |
| |
| |
| |
| |
| |
| if(to.path==='/main'){ |
| const token=localStorage.getItem('token'); |
| |
| if(token){ |
| next() |
| }else{ |
| next('/login') |
| } |
| }else{ |
| next() |
| } |
| }) |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!