【Vue项目】去哪儿网APP②首页开发
首页开发中的重难点
重点思想
第一次接触一个完整的Vue项目,从看视频一步一步的做,个人觉得最重要的思想就是,懂得页面组件化这个概念。
将一个页面分成各个部分,例如首页,将它分成头部、轮播图、图标区域、热销推荐区域以及周末去哪儿区域,每个区域都是由一个组件来开发实现。这样实现了页面中每个部分的开发实现自由,以及提高后续对某个部分修改维护的效率。
在一个组件中,分别由三个部分组成,分别是模板template(页面展示代码),数据script(业务实现代码),样式style(页面布局代码)。
本次开发中,使用了stylus这个CSS预处理器。因此最终整个组件的初始化如下:
<template>
</template>
lll
<script>
export default {
}
</script>
<style lang="stylus" scoped>
</style>
其中,style中的scoped关键字代表该样式只对当前组件有效,实现局部化样式。
flex:1
在header-input区域中(中间输入框区域),采用flex布局。在左右区域设置width的情况下,设置flex:1,实现中间区域在剩下的区域间均匀分配空间(自由拓展)。
使用iconfont图标
首先,在iconfont官网选择好要使用的图标,将之加入购物车并下载。
接着,将下载后的尾缀.svg .ttf .woff .eot的字体文件放入styles中的iconfont文件夹中,并将iconfont.css文件放入styles文件夹中,还要改变iconfont.css中文件加载路径。
最后,在mian.js中引入iconfont.css文件:
import './assets/styles/iconfont.css'
使用vue-awesome-swiper实现轮播效果
首页开发中,轮播图区域、图标区域皆使用了swiper实现了轮播效果。
- 首先根据GitHub上vue-awesome-swiper,安装并引入使用swiper。
- 更多详细使用则是参考这个网站:vue轮播(完整详细版),在这个网站上可以参考实现轮播图自动切换的效果
- 在swiper中绑定了:options=“swiperOption”,所以我们也要在data中添加swiperOption对象
data () {
return {
swiperOption: {
pagination: '.swiper-pagination',
loop: true,
// 自动切换效果
autoplay: true,
speed: 1500
}
}
}
实现带有分页器的轮播
- 首先,需要在data中定义以下代码:
data () {
return {
swiperOption: {
//定义了轮播页码
pagination: '.swiper-pagination'
}
}
}
- 如果想要修改页码的颜色,则需要采用样式穿透(>>>):
.icons >>> .swiper-pagination-bullet-active
background: $bgColor !important
- 如果实现轮播的自动播放以及循环播放,则可定义如下代码:
swiperOption: {
pagination: '.swiper-pagination',
//循环播放
loop: true,
// 自动切换效果
autoplay: true,
speed: 3000
}
实现有分页效果的图标(icon)轮播区域
- 使用计算属性实现分页功能:list为icon的数据。一页只能有8个图标,**遍历list,当多余8个时,就要放到第二页去,即放到下一个轮播图中。**例如第九个icon,page=Math.floor(9 / 8)=1;说明第九个icon在第1页(页码从0开始算),这样就生成了带有分页效果的icon轮播区域
computed: {
pages () {
const pages = []
this.list.forEach((item, index) => {
const page = Math.floor(index / 8)
if (!pages[page]) {
pages[page] = []
}
pages[page].push(item)
})
return pages
}
}
- 之后在swiper-slide中用v-for先遍历pages,生成多个swiper-slide,每个swiper-slide对应一页。在每个swiper-slide中遍历pages中的每个item,生成每页的icon,简单来说就是两个for循环的嵌套。
<swiper :options="swiperOption">
<swiper-slide v-for="(page,index) of pages" :key="index">
<div class="icon" v-for="item of page" :key="item.id">
<div class="icon-img">
<img class="icon-img-content" :src="item.imgUrl" />
</div>
<p class="icon-desc">{{item.desc}}</p>
</div>
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
用padding-bottom实现固定宽高比
将height设置为0,padding-bottom会以宽度为标准撑出高度:
如以下代码:
height :0
padding-bottom :53%
这个方法也可以解决图片的抖动问题。
实现文本太多,显示省略号(…)效果:
overflow :hidden
white-space :nowrap
text-overflow :ellipsis
此处css代码会经常用到,可建立一个styl文件,将其存为函数方便复用。
保证内容不超出父盒子
在一个flex布局中,设置flex:1,min-width: 0,保证内容不超出外层容器
如果没有设置min-width,当内容大于剩余盒子宽度时会超出父盒子,设置min-width保证内容局限在父盒子内。
使用vue axios来获取数据
axios是通过promise实现对ajax技术的一种封装
- 首先使用命令
$ npm install axios --save
安装以及在文件中引入。 - 使用以下代码实现使用axios来获取数据
methods: {
getHomeInfo () {
axios.get('/api/index.json')
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
res = res.data
if (res.ret && res.data) {
const data = res.data
this.city = data.city
this.swiperList = data.swiperList
this.iconList = data.iconList
this.recommendList = data.recommendList
this.weekendList = data.weekendList
}
}
},
mounted () {
this.getHomeInfo()
}
- 在项目中,static文件夹是可以直接被外部访问到的,因此可以用来存放数据index.json。并且可以在.gitignore文件中设置static文件夹不上传至线上平台。
- 如果我们的代码要上线,那我们的地址就要写成/api/index.json类似格式。此时,可以借助webpack-dev-server给我们提供了一个在config文件夹下的index.js中的proxyTable这个***功能来解决这个问题。
proxyTable: {
'/api': {
target: 'http://localhost:8080',
pathRewrite:{
'^/api': '/static/mock'
}
}
}
解决轮播图在使用axios获取数据后,出现刷新后首先播放最后一张图的问题
在swiper中,使用v-if="list.length"
判断list数组是否已经获取了ajax数据,如果数组为空时,swiper不会被创建。
不过为了减少在模板中出现逻辑性代码,采用计算属性来解决这个问题:
computed: {
showSwiper () {
return this.list.length
}
}
v-if则改为:v-if="showSwiper"
代码优化
- header中的背景色经常会被使用到,所以可以优化一下代码,在styles文件夹下创建一个varibles.styl文件,编写以下代码:
$bgColor = #00bcd4
- 为了简化引入路径,可以在build文件夹下的webpack.base.conf.js中编写以下代码:
'styles': resolve('src/assets/styles')
保存后,可以在引入varibles.styl时,使用该简化后的路径:
@import'~styles/varibles.styl'
注意:在css中引入样式时需要在import前加@;
在css中引入时需要在前面加~