Vue-Router路由系统
Vue路由基础
是什么
为什么
- 整体不刷新页面,用户体验更好
- 数据传递容易, 开发效率高
- 开发成本高(需要学习专门知识)
- 首次加载会比较慢一点。不利于seo
单页面应用
概念: 所有的业务都在一个页面编写, 只有一个html
好处: 开发效率高, 用户体验好;
如何切换场景:依赖路由切换显示
vue-router基本使用
概念:vue-router本质是一个第三方包
好处:
- 它和 Vue.js 深度集成
- 可以定义 - 视图表(映射规则)
- 模块化的
- 提供2个内置全局组件
- 声明式导航自动激活的 CSS class 的链接
步骤:
1 const routes = [ 2 { 3 path: "/find", 4 component: Find 5 }, 6 { 7 path: "/my", 8 component: My 9 }, 10 { 11 path: "/part", 12 component: Part 13 } 14 ]
5. 用规则生成路由对象
1 const router = new VueRouter({ 2 routes 3 })
组件分类
页面组件:配合路由, 切换页面
复用组件:页面组件, 重复渲染结构一样的标签
声明式导航
基础应用
过程
- vue-router提供了一个全局组件 router-link
- router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
- router-link提供了声明式导航高亮的功能(自带类名)
- 自己设置样式
1 <template> 2 <div> 3 <div class="footer_wrap"> 4 <!-- a标签形式 --> 5 <!-- <a href="#/find">发现音乐</a> 6 <a href="#/my">我的音乐</a> 7 <a href="#/part">朋友</a> --> 8 9 <router-link to="/find">发现音乐</router-link> 10 <router-link to="/my">我的音乐</router-link> 11 <router-link to="/part">朋友</router-link> 12 </div> 13 <div class="top"> 14 <router-view></router-view> 15 </div> 16 </div> 17 </template> 18 19 <script> 20 export default {}; 21 </script> 22 23 <style scoped> 24 /* 自己定义高亮样式 */ 25 .footer_wrap .router-link-active { 26 color: white; 27 background: black; 28 } 29 </style>
总结:
用router-link配合to, 实现点击切换路由;可用全局组件router-link来替代a标签
在router-link上的to属性传值, 语法格式如下
-
/path?参数名=值
-
/path/值 – 需要路由对象提前配置 path: “/path/参数名”
对应页面组件接收传递过来的值:
-
-
$route.params.参数名
示列
components/Part.vue
1 <template> 2 <div> 3 <p>关注明星</p> 4 <p>发现精彩</p> 5 <p>寻找伙伴</p> 6 <p>加入我们</p> 7 <p>人名: {{ $route.query.name }} -- {{ $route.params.username }}</p> 8 </div> 9 </template>
路由定义
1 { 2 path: "/part", 3 component: Part 4 }, 5 { 6 path: "/part/:username", // 有:的路径代表要接收具体的值 7 component: Part 8 },
导航跳转, 传值给MyGoods.vue组件
1 <router-link to="/part?name=小传">朋友-小传</router-link>
2 <router-link to="/part/小智">朋友-小智</router-link>
总结:?key=value 用$route.query.key 取值;/值 提前在路由规则/path/:key 用$route.params.key 取值
重定向和模式
重定向
-
-
redirect是设置要重定到默认页面(如页面一打开默认首页显示)
1 const routes = [ 2 { 3 path: "/", // 默认hash值路径,必须是/,后面不能带其他路径 4 redirect: "/find" // 重定向到/find 5 // 浏览器url中#后的路径被改变成/find-重新匹配数组规则 6 } 7 ]
总结: 强制重定向后, 还会重新来数组里匹配一次规则
1 <template> 2 <img src="../assets/404.png" alt=""> 3 </template> 4 5 <script> 6 export default { 7 8 } 9 </script> 10 11 <style scoped> 12 img{ 13 width: 100%; 14 } 15 </style>
在main.js - 修改路由配置
1 import NotFound from '@/views/NotFound' 2 3 const routes = [ 4 // ...省略了其他配置 5 // 404在最后(规则是从前往后逐个比较path) 6 { 7 path: "*", 8 component: NotFound 9 } 10 ]
总结: 如果路由未命中任何规则, 给出一个兜底的404页面
1 const router = new VueRouter({ 2 routes, 3 mode: "history" // 打包上线后需要后台支持, 模式是hash 4 })
编程式导航用(JS代码来进行跳转)
1 { 2 path: "/find", 3 name: "Find", 4 component: Find 5 }, 6 { 7 path: "/my", 8 name: "My", 9 component: My 10 }, 11 { 12 path: "/part", 13 name: "Part", 14 component: Part 15 },
App.vue - 换成span 配合js的编程式导航跳转
1 <template> 2 <div> 3 <div class="footer_wrap"> 4 <span @click="btn('/find', 'Find')">发现音乐</span> 5 <span @click="btn('/my', 'My')">我的音乐</span> 6 <span @click="btn('/part', 'Part')">朋友</span> 7 </div> 8 <div class="top"> 9 <router-view></router-view> 10 </div> 11 </div> 12 </template> 13 14 <script> 15 // 目标: 编程式导航 - js方式跳转路由 16 // 语法: 17 // this.$router.push({path: "路由路径"}) 18 // this.$router.push({name: "路由名"}) 19 // 注意: 20 // 虽然用name跳转, 但是url的hash值还是切换path路径值 21 // 场景: 22 // 方便修改: name路由名(在页面上看不见随便定义) 23 // path可以在url的hash值看到(尽量符合组内规范) 24 export default { 25 methods: { 26 btn(targetPath, targetName){ 27 // 方式1: path跳转 28 this.$router.push({ 29 // path: targetPath, 30 name: targetName 31 }) 32 } 33 } 34 }; 35 </script>
1 this.$router.push({ 2 path: "路由路径" 3 name: "路由名", 4 query: { 5 "参数名": 值 6 } 7 params: { 8 "参数名": 值 9 } 10 }) 11 12 // 对应路由接收 $route.params.参数名 取值 13 // 对应路由接收 $route.query.参数名 取值
1 <template> 2 <div> 3 <div class="footer_wrap"> 4 <span @click="btn('/find', 'Find')">发现音乐</span> 5 <span @click="btn('/my', 'My')">我的音乐</span> 6 <span @click="oneBtn">朋友-小传</span> 7 <span @click="twoBtn">朋友-小智</span> 8 </div> 9 <div class="top"> 10 <router-view></router-view> 11 </div> 12 </div> 13 </template> 14 15 <script> 16 // 目标: 编程式导航 - 跳转路由传参 17 // 方式1: 18 // params => $route.params.参数名 19 // 方式2: 20 // query => $route.query.参数名 21 // 重要: path会自动忽略params 22 // 推荐: name+query方式传参 23 // 注意: 如果当前url上"hash值和?参数"与你要跳转到的"hash值和?参数"一致, 爆出冗余导航的问题, 不会跳转路由 24 export default { 25 methods: { 26 btn(targetPath, targetName){ 27 // 方式1: path跳转 28 this.$router.push({ 29 // path: targetPath, 30 name: targetName 31 }) 32 }, 33 oneBtn(){ 34 this.$router.push({ 35 name: 'Part', 36 params: { 37 username: '小传' 38 } 39 }) 40 }, 41 twoBtn(){ 42 this.$router.push({ 43 name: 'Part', 44 query: { 45 name: '小智' 46 } 47 }) 48 } 49 } 50 }; 51 </script>
路由嵌套
-
src/views/Find.vue -- 发现音乐页
src/views/My.vue -- 我的音乐页
src/views/Second/Recommend.vue -- 发现音乐页 / 推荐页面
src/views/Second/Ranking.vue -- 发现音乐页 / 排行榜页面
src/views/Second/SongList.vue -- 发现音乐页 / 歌单页面
-
main.js– 继续配置2级路由
一级路由path从/开始定义
二级路由往后path直接写名字, 无需/开头
嵌套路由在上级路由的children数组里编写路由信息对象
-
说明:
App.vue的router-view负责发现音乐和我的音乐页面, 切换
Find.vue的的router-view负责发现音乐下的, 三个页面, 切换
1 <template> 2 <div> 3 <!-- <p>推荐</p> 4 <p>排行榜</p> 5 <p>歌单</p> --> 6 <div class="nav_main"> 7 <router-link to="/find/recommend">推荐</router-link> 8 <router-link to="/find/ranking">排行榜</router-link> 9 <router-link to="/find/songlist">歌单</router-link> 10 </div> 11 12 <div style="1px solid red;"> 13 <router-view></router-view> 14 </div> 15 </div> 16 </template> 17 18 <script> 19 export default {}; 20 </script> 21 22 <style scoped> 23 .nav_main { 24 background-color: red; 25 color: white; 26 padding: 10px 0; 27 } 28 .nav_main a { 29 text-align: center; 30 text-decoration: none; 31 color: white; 32 font-size: 12px; 33 margin: 7px 17px 0; 34 padding: 0px 15px 2px 15px; 35 height: 20px; 36 display: inline-block; 37 line-height: 20px; 38 border-radius: 20px; 39 } 40 .nav_main a:hover { 41 background-color: brown; 42 } 43 .nav_main .router-link-active{ 44 background-color: brown; 45 } 46 </style>
配置路由规则-二级路由展示
1 const routes = [ 2 // ...省略其他 3 { 4 path: "/find", 5 name: "Find", 6 component: Find, 7 children: [ 8 { 9 path: "recommend", 10 component: Recommend 11 }, 12 { 13 path: "ranking", 14 component: Ranking 15 }, 16 { 17 path: "songlist", 18 component: SongList 19 } 20 ] 21 } 22 // ...省略其他 23 ]
App.vue, 外层的router-view负责发现音乐和我的音乐页面切换
Find.vue 内层的router-view负责发现音乐下的子tab对应的组件切换
总结: 嵌套路由, 找准在哪个页面里写router-view和对应规则里写children
语法: router.beforeEach((to, from, next)=>{//路由跳转"之前"先执行这里, 决定是否跳转})
1 // 目标: 路由守卫 2 // 场景: 当你要对路由权限判断时 3 // 语法: router.beforeEach((to, from, next)=>{//路由跳转"之前"先执行这里, 决定是否跳转}) 4 // 参数1: 要跳转到的路由 (路由对象信息) 目标 5 // 参数2: 从哪里跳转的路由 (路由对象信息) 来源 6 // 参数3: 函数体 - next()才会让路由正常的跳转切换, next(false)在原地停留, next("强制修改到另一个路由路径上") 7 // 注意: 如果不调用next, 页面留在原地 8 9 // 例子: 判断用户是否登录, 是否决定去"我的音乐"/my 10 const isLogin = true; // 登录状态(未登录) 11 router.beforeEach((to, from, next) => { 12 if (to.path === "/my" && isLogin === false) { 13 alert("请登录") 14 next(false) // 阻止路由跳转 15 } else { 16 next() // 正常放行 17 } 18 })