大家好, Capybara 继续与大家一起学习Vue框架。书读百遍其义自见。
day06
路由进阶
路由模块封装
router/index.js
所抽离内容包括:导入组件、(额外需要)导入Vue、导入VueRouter插件、
创建路由对象、导出路由对象
需要注意路径写法(推荐使用绝对路径 @代表当前src目录)
效果:
使用router-link替代a标签实现高亮
本质渲染还是a标签,to无需#,且能高亮
代码:
<template> <div> <div class="footer_wrap"> <router-link to="/find">发现音乐</router-link> <router-link to="/my">我的音乐</router-link> <router-link to="/friend">朋友</router-link> </div> <div class="top"> <!-- 路由出口 → 匹配的组件所展示的位置 --> <router-view></router-view> </div> </div> </template> ……
效果:
本质是a元素
自带两个可使用高亮类名:
选中时更改背景颜色:
小结:
精确匹配&模糊匹配
关于两个类名
在url后加上one,仍然匹配(router-link-active)
设置 .router-link-active
小结:
自定义匹配的类名
长有长的好处,不容易重名。
配置代码(router/index.js):
import Find from '@/views/Find' import My from '@/views/My' import Friend from '@/views/Friend' import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) // VueRouter插件初始化 // 创建了一个路由对象 const router = new VueRouter({ // routes 路由规则们 // route 一条路由规则 { path: 路径, component: 组件 } routes: [ { path: '/find', component: Find }, { path: '/my', component: My }, { path: '/friend', component: Friend }, ], // link自定义高亮类名 linkActiveClass: 'active', // 配置模糊匹配的类名 linkExactActiveClass: 'exact-active' // 配置精确匹配的类名 }) export default router
浏览器可看到,类名发送变化:
小结:
声明式导航-跳转传参
传参方式有两种:
1.查询参数传参
点击链接,从首页跳转到搜索页,希望把链接信息传过去
直接跳转
(不带参数)关键字写死
携带查询参数:
在页面获取参数:
页面显示参数:
如果想要基于参数去发送请求?
在哪发?—— created
获取参
数?this.$route.query.key
2.动态路由传参
代码:
(router/index.js)
import Home from '../views/Home.vue' import Search from '../views/Search.vue' import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) // VueRouter插件初始化 // 创建了一个路由对象 const router = new VueRouter({ routes: [ { path: '/home', component: Home }, { path: '/search/:words', component: Search } ] }) export default router
home.vue
<template> <div class="home"> <div class="logo-box"></div> <div class="search-box"> <input type="text"> <button>搜索一下</button> </div> <div class="hot-link"> 热门搜索: <router-link to="/search/黑马程序员">黑马程序员</router-link> <router-link to="/search/前端培训">前端培训</router-link> <router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link> </div> </div> </template> <script> export default { name: 'FindMusic' } </script> <style> .logo-box { height: 150px; background: url('../assets/logo.jpeg') no-repeat center; } .search-box { display: flex; justify-content: center; } .search-box input { width: 400px; height: 30px; line-height: 30px; border: 2px solid #c4c7ce; border-radius: 4px 0 0 4px; outline: none; } .search-box input:focus { border: 2px solid #ad2a26; } .search-box button { width: 100px; height: 36px; border: none; background-color: #ad2a26; color: #fff; position: relative; left: -2px; border-radius: 0 4px 4px 0; } .hot-link { width: 508px; height: 60px; line-height: 60px; margin: 0 auto; } .hot-link a { margin: 0 5px; } </style>
效果:
两种传参方式的区别
小结:
动态路由参数可选符
路由重定向
redirect
路由404
添加一个NotFound组件
router/index.js
import Home from '@/views/Home' import Search from '@/views/Search' import NotFound from '@/views/NotFound' import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) // VueRouter插件初始化 // 创建了一个路由对象 const router = new VueRouter({ routes: [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { path: '/search/:words?', component: Search }, { path: '*', component: NotFound } ] }) export default router
效果(访问 list 无匹配):
路由模式
router/index.js
import Home from '@/views/Home' import Search from '@/views/Search' import NotFound from '@/views/NotFound' import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) // VueRouter插件初始化 // 创建了一个路由对象 const router = new VueRouter({ // 注意:一旦采用了 history 模式,地址栏就没有 #,需要后台配置访问规则 mode: 'history', routes: [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { name: 'search', path: '/search/:words?', component: Search }, { path: '*', component: NotFound } ] }) export default router
编程式导航
用JS代码来进行跳转
1. 通过路径的方式跳转
// (1) this.$router.push('路由路径') [简写]
// this.$router.push('/search')
// (2) this.$router.push({ [完整写法]
// path: '路由路径'
// })
// this.$router.push({
// path: '/search'
// })
2. 通过命名路由的方式跳转
(需要给路由起名字) 适合长路径
// this.$router.push({
// name: '路由名'
// })
router/index.js
import Home from '@/views/Home' import Search from '@/views/Search' import NotFound from '@/views/NotFound' import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) // VueRouter插件初始化 // 创建了一个路由对象 const router = new VueRouter({ // 注意:一旦采用了 history 模式,地址栏就没有 #,需要后台配置访问规则 mode: 'history', routes: [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { name: 'search', path: '/search/:words?', component: Search }, { path: '*', component: NotFound } ] }) export default router
Home.vue
<template> <div class="home"> <div class="logo-box"></div> <div class="search-box"> <input type="text"> <button @click="goSearch">搜索一下</button> </div> <div class="hot-link"> 热门搜索: <router-link to="/search/黑马程序员">黑马程序员</router-link> <router-link to="/search/前端培训">前端培训</router-link> <router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link> </div> </div> </template> <script> export default { name: 'FindMusic', methods: { goSearch () { // 1. 通过路径的方式跳转 // (1) this.$router.push('路由路径') [简写] // this.$router.push('/search') // (2) this.$router.push({ [完整写法] // path: '路由路径' // }) // this.$router.push({ // path: '/search' // }) // 2. 通过命名路由的方式跳转 (需要给路由起名字) 适合长路径 // this.$router.push({ // name: '路由名' // }) this.$router.push({ name: 'search' }) } } } </script> <style> .logo-box { height: 150px; background: url('@/assets/logo.jpeg') no-repeat center; } .search-box { display: flex; justify-content: center; } .search-box input { width: 400px; height: 30px; line-height: 30px; border: 2px solid #c4c7ce; border-radius: 4px 0 0 4px; outline: none; } .search-box input:focus { border: 2px solid #ad2a26; } .search-box button { width: 100px; height: 36px; border: none; background-color: #ad2a26; color: #fff; position: relative; left: -2px; border-radius: 0 4px 4px 0; } .hot-link { width: 508px; height: 60px; line-height: 60px; margin: 0 auto; } .hot-link a { margin: 0 5px; } </style>
小结:
编程式导航传参 ( 查询参数传参 & 动态路由传参 )
path路径跳转传参
传入输入框内容:
两种传参方式:查询参数传参和动态路由传参 都支持
完整写法更适合多参数情况(不用一个一个拼接)
name命名路由跳转传参
在路由中配置动态路由
使用params传参
在所跳转的组件中,通过 $route.params.参数名 获取传入参数值
代码:
router/index.js
import Home from '@/views/Home' import Search from '@/views/Search' import NotFound from '@/views/NotFound' import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) // VueRouter插件初始化 // 创建了一个路由对象 const router = new VueRouter({ // 注意:一旦采用了 history 模式,地址栏就没有 #,需要后台配置访问规则 mode: 'history', routes: [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { name: 'search', path: '/search/:words?', component: Search }, { path: '*', component: NotFound } ] }) export default router
Home.vue
<template> <div class="home"> <div class="logo-box"></div> <div class="search-box"> <input v-model="inpValue" type="text"> <button @click="goSearch">搜索一下</button> </div> <div class="hot-link"> 热门搜索: <router-link to="/search/黑马程序员">黑马程序员</router-link> <router-link to="/search/前端培训">前端培训</router-link> <router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link> </div> </div> </template> <script> export default { name: 'FindMusic', data () { return { inpValue: '' } }, methods: { goSearch () { // 1. 通过路径的方式跳转 // (1) this.$router.push('路由路径') [简写] // this.$router.push('路由路径?参数名=参数值') // this.$router.push('/search') // this.$router.push(`/search?key=${this.inpValue}`) // this.$router.push(`/search/${this.inpValue}`) // (2) this.$router.push({ [完整写法] 更适合传参 // path: '路由路径' // query: { // 参数名: 参数值, // 参数名: 参数值 // } // }) // this.$router.push({ // path: '/search', // query: { // key: this.inpValue // } // }) // this.$router.push({ // path: `/search/${this.inpValue}` // }) // 2. 通过命名路由的方式跳转 (需要给路由起名字) 适合长路径 // this.$router.push({ // name: '路由名' // query: { 参数名: 参数值 }, // params: { 参数名: 参数值 } // }) this.$router.push({ name: 'search', // query: { // key: this.inpValue // } params: { words: this.inpValue } }) } } } </script> ……
小结:
个人总结
路由导航 传参 跳转 三问:
1.哪种路由导航?
2.传参方式是什么?
3.如果是编程式导航,跳转方式是什么?
路由导航的种类有两种:
1.声明式导航——使用router-link组件,点击后跳转 路由跳转的方法:<router-link to=" ">
2.编程式导航——触发事件,用JS代码来进行跳转 路由跳转的方法: this.$router.push()
路由传参方式也有两种:
1.查询参数传参——在路由中拼接查询参数 形式:?key=value
传过去的参数,通过 this.$route.query.key 获取
2.动态路由传参——在路由中直接拼接参数 形式:/value (前提:在router中配置动态路由 '…/:key' )
传过去的参数,通过 this.$route.params.key 获取
编程式导航的跳转方式有两种:
① path 路径跳转
② name 命名路由跳转
传参方式 和跳转方式可以两两组合,实现 携带参数的路由跳转
其中$router.push() 方法的实参有两种写法:($router.push() ——> 编程式导航 )
1.简写:$router.push('路由路径')
①编程式导航-查询参数传参-path路径跳转
②编程式导航-动态路由传参-path路径跳转
2.完整写法(更适合传参,不用一个一个参数拼接)
其中,命名路由跳转只能使用完整写法:
①编程式导航-查询参数传参-path路径跳转
②编程式导航-动态路由传参-path路径跳转
③编程式导航-查询参数传参-name命名跳转
④编程式导航-动态路由传参-name命名跳转
根据查询
声明式导航 也可以使用 命名路由跳转 方式
个人认为:
在元素(router-link)的属性写一个对象(JS代码)阅读性较差,故少用
综合案例:面经基础版
案例分析:
面经基础版-路由配置
一级路由
二级路由(还要准备第二级路由出口)
二级路由出口
高亮,a换成router-link,推荐使用模糊匹配类名,router-link-active
加上高亮样式
效果:
面经基础版-首页请求渲染
步骤:
请求数据:
然后在模板中渲染即可。
面经基础版-传参(查询参数&动态路由)
注册点击事件:
传参方式:
查询参数传参:
地址栏处会带上id:
动态路由传参(单个参数更优雅方便):
配置动态路由
不用写上 id=
修复小bug
回到首页时:
出现空白(因为没有匹配到任何二级路由)
解决办法:重定向
给头部导航的返回小箭头添加返回功能( $router.back() ):
面经基础版-详情页渲染
发送请求获取数据:
插值语法渲染:
有时候出现空白:
有的内容没渲染出来
为什么?发请求需要时间,有一小段时间,article为空。
解决方法:加上v-if,有内容才去渲染
面经基础版-缓存组件
keep-alive
实操:
detail也被缓存了(不需要被缓存)
注意:name优先级更高
使用keep-alive的include属性
被缓存组件多两个生命周期钩子
实操:
进入时:
点击面经进入详情页面后,再返回,created mounted destroyed不会再被触发。
如果希望回到首页有提示等,在哪实现?
提供了actived deactived
小结:
自定义创建项目
1.安装脚手架 (已安装)
npm i @vue/cli -g
2.创建项目
vue create hm-exp-mobile
- 选项
Vue CLI v5.0.8 ? Please pick a preset: Default ([Vue 3] babel, eslint) Default ([Vue 2] babel, eslint) > Manually select features 选自定义
- 手动选择功能
- 选择vue的版本
3.x > 2.x
- 是否使用history模式
- 选择css预处理
- 选择eslint的风格 (eslint 代码规范的检验工具,检验代码是否符合规范)
- 比如:const age = 18; => 报错!多加了分号!后面有工具,一保存,全部格式化成最规范的样子
- 选择校验的时机 (直接回车)
- 选择配置文件的生成方式 (直接回车)
- 是否保存预设,下次直接使用? => 不保存,输入 N
- 等待安装,项目初始化完成
- 启动项目
cd npm run serve
ESLint手动修正代码规范错误
举例:
使用注意:
以 vue create 的文件夹(目录)作为根目录
运行报错:
根据规范说明找错:
理解错误:
ESLint自动修正代码规范错误
设置——>打开设置