Vue(6)
一.路由板块封装
(1)路由的封装抽离
目标:将路由板块抽离出来
好处:拆分板块,利于维护
// 路由的使用步骤 5 + 2
// 5个基础步骤
// 1. 下载 v3.6.5
// 2. 引入
// 3. 安装注册 Vue.use(Vue插件)
// 4. 创建路由对象
// 5. 注入到new Vue中,建立关联
// 2个核心步骤
// 1. 建组件(views目录),配规则
// 2. 准备导航链接,配置路由出口(匹配的组件展示的位置)
import Find from './views/Find'
import My from './views/My'
import Friend from './views/Friend'
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 },
]
})
Vue.config.productionTip = false
(2)声明式导航 - 导航链接
使用router-link代替a标签实现高亮
①能跳转,配置to属性指定路径(必须),本质还是a标签,to无需#
②能高亮,默认就会提供高亮类名,可以直接设置高亮样式
<template>
<div>
<div class="footer_wrap">
<router-link href="#/find">发现音乐</router-link>
<router-link href="#/my">我的音乐</router-link>
<router-link href="#/friend">朋友</router-link>
</div>
<div class="top">
<!-- 路由出口 → 匹配的组件所展示的位置 -->
<router-view></router-view>
</div>
</div>
</template>
(3)声明式导航-两个类名
①router-link-active模糊匹配(用的多)
②router-link-exact-active精确匹配
const router = new VueRouter({
// routes 路由规则们
// route 一条路由规则 { path: 路径, component: 组件 }
routes: [...],
linkActiveClass:"类名1",
linkExactActiveClass:"类名2"
})
(4)声明式导航-跳转传参
目标:在跳转路由时进行传值
1.查询参数传参
①语法格式:to = “/path?参数值=值”
②对应页面组件接受传递和过来的值:$routw . query . 参数名
2.动态路由传参
①配置动态路由
// 创建了一个路由对象
const router = new VueRouter({
routes: [
{ path: '/home', component: Home },
{ path: '/search/:words?', component: Search }
]
})
②配置导航链接 to = ”/ path / 参数值
③对应页面组件接受传递过来的值 $routw . params . 参数名
(5)Vue路由重定向
匹配path后,强制跳转path路径
语法:{ path:匹配路径,redirect:重定向的路径 }
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/home' },
{ path: '/home', component: Home },
{ path: '/search/:words?', component: Search }
]
})
(6)Vue路由-404
语法:path:" * "(任意路径)- 前面不匹配就命中最后一个
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/home' },
{ path: '/home', component: Home },
{ path: '/search/:words?', component: Search },
{ path: '*', component: NotFound }
]
})
(7)Vue路由 - 模式设置
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 }
]
})
(8)编程式导航 - 基本跳转
①path路径跳转(简易方便)
②name命名路由跳转(适合path路径长的场景)
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>
(9)编程式导航 - 路由传参
①path路径跳转传参(query传参)
②name命名路由跳转传参
this.$router.push(`/路径?参数名1=参数值1 & 参数名2=参数值2)
this.$router.push({
path:`/路径`,
qurey:{
参数名1='参数值1',
参数名2='参数值2'
}
})
二.面经基础版
(1)路由配置
配路由
①首页和面经详情,两个一级路由
②首页内嵌四个可切换页面
(2)页面请求渲染
2.实现功能
①首页请求渲染
②跳转传参到详情页,详情页渲染
③组件缓存,优化性能
<template>
<div class="article-page">
<div
class="article-item"
>
<div class="head">
<img src="http://teachoss.itheima.net/heimaQuestionMiniapp/%E5%AE%98%E6%96%B9%E9%BB%98%E8%AE%A4%E5%A4%B4%E5%83%8F%402x.png" alt="" />
<div class="con">
<p class="title">百度前端面经</p>
<p class="other">青春, 那么骚 | 2022-01-20</p>
</div>
</div>
<div class="body">
虽然百度这几年发展势头落后于AT,甚至快被京东赶上了,毕竟瘦死的骆驼比马大,面试还是相当有难度和水准的。一面1.询问你的项目经验、学习经历、主修语言(照实答)2.解释ES6的暂时性死区( let 和 var 的区别)3.箭头函数、闭包、异步(老生常谈,参见上文)4.高阶函数(呃……我真不太清楚这是啥,听起来挺像闭包的)5.求N的阶乘末尾有多少个0,在线码代码或讲思路(求因数,统计2、5、10的个数
</div>
<div class="foot">点赞 44 | 浏览 315</div>
</div>
</div>
</template>
<script>
// 请求地址: https://mock.boxuegu.com/mock/3083/articles
// 请求方式: get
export default {
name: 'ArticlePage',
data () {
return {
}
}
}
</script>
<style lang="less" scoped>
.article-page {
background: #f5f5f5;
}
.article-item {
margin-bottom: 10px;
background: #fff;
padding: 10px 15px;
.head {
display: flex;
img {
width: 40px;
height: 40px;
border-radius: 50%;
overflow: hidden;
}
.con {
flex: 1;
overflow: hidden;
padding-left: 15px;
p {
margin: 0;
line-height: 1.5;
&.title {
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
white-space: nowrap;
}
&.other {
font-size: 10px;
color: #999;
}
}
}
}
.body {
font-size: 14px;
color: #666;
line-height: 1.6;
margin-top: 10px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.foot {
font-size: 12px;
color: #999;
margin-top: 10px;
}
}
</style>
<template>
<div class="article-detail-page">
<nav class="nav"><span class="back"><</span> 面经详情</nav>
<header class="header">
<h1>百度前端面经</h1>
<p>2022-01-20 | 315 浏览量 | 44 点赞数</p>
<p>
<img
src="http://teachoss.itheima.net/heimaQuestionMiniapp/%E5%AE%98%E6%96%B9%E9%BB%98%E8%AE%A4%E5%A4%B4%E5%83%8F%402x.png"
alt=""
/>
<span>青春少年</span>
</p>
</header>
<main class="body">
虽然百度这几年发展势头落后于AT, 甚至快被京东赶上了,毕竟瘦死的骆驼比马大,
面试还是相当有难度和水准的, 一面.....
</main>
</div>
</template>
<script>
// 请求地址: https://mock.boxuegu.com/mock/3083/articles/:id
// 请求方式: get
export default {
name: "ArticleDetailPage",
data() {
return {
}
}
}
</script>
<style lang="less" scoped>
.article-detail-page {
.nav {
height: 44px;
border-bottom: 1px solid #e4e4e4;
line-height: 44px;
text-align: center;
.back {
font-size: 18px;
color: #666;
position: absolute;
left: 10px;
top: 0;
transform: scale(1, 1.5);
}
}
.header {
padding: 0 15px;
p {
color: #999;
font-size: 12px;
display: flex;
align-items: center;
}
img {
width: 40px;
height: 40px;
border-radius: 50%;
overflow: hidden;
}
}
.body {
padding: 0 15px;
}
}
</style>
<template>
<div class="h5-wrapper">
<div class="content">
内容
</div>
<nav class="tabbar">
<a href="#/article">面经</a>
<a href="#/collect">收藏</a>
<a href="#/like">喜欢</a>
<a href="#/user">我的</a>
</nav>
</div>
</template>
<script>
export default {
name: "LayoutPage",
}
</script>
<style>
body {
margin: 0;
padding: 0;
}
</style>
<style lang="less" scoped>
.h5-wrapper {
.content {
margin-bottom: 51px;
}
.tabbar {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
display: flex;
background: #fff;
border-top: 1px solid #e4e4e4;
a {
flex: 1;
text-decoration: none;
font-size: 14px;
color: #333;
-webkit-tap-highlight-color: transparent;
}
}
}
</style>
<template>
<div class="h5-wrapper">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "h5-wrapper",
}
</script>
<style>
body {
margin: 0;
padding: 0;
}
</style>
<style lang="less" scoped>
.h5-wrapper {
.content {
margin-bottom: 51px;
}
.tabbar {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
display: flex;
background: #fff;
border-top: 1px solid #e4e4e4;
a {
flex: 1;
text-decoration: none;
font-size: 14px;
color: #333;
-webkit-tap-highlight-color: transparent;
&.router-link-active {
color: #fa0;
}
}
}
}
</style>