推荐页面开发
推荐页面分为两个页面:首页和歌单详情页面
首页
首页分为:轮播图、歌单列表
轮播图
参考QQ音乐抓取轮播图数据,以jsonp的形式返回数据。首先,对jsonp进行封装。
了解jsonp:https://github.com/webmodules/jsonp
jsonp.js
|
|
编写轮播图组件
slider.vue
|
|
抓取轮播图数据
recommend.js
|
|
在recommend.vue
组件里实现获取到轮播图数据
|
|
效果如图:
如上图很不符合我们的要求,我在这里使用第三方插件better-scroll来实现轮播图滚动功能。
better-scroll
better-scroll 是什么
better-scroll 是一款重点解决移动端(未来可能会考虑 PC 端)各种滚动场景需求的插件。它是基于原生 JS 实现的,不依赖任何框架。
better-scroll滚动原理:浏览器的滚动条大家都会遇到,当页面内容的高度超过视口高度的时候,会出现纵向滚动条;当页面内容的宽度超过视口宽度的时候,会出现横向滚动条。也就是当我们的视口展示不下内容的时候,会通过滚动条的方式让用户滚动屏幕看到剩余的内容。
安装:
|
|
了解better-scroll具体参考:http://npm.taobao.org/package/better-scroll
设置slider的属性
slider.vue
|
|
有时候会出现初始化后不能滚动或者报错,是因为在初始化时没有渲染或者宽度或高度计算出错,为了保证渲染正确使用mounted钩子做一些初始化操作_setSliderWidth()
、_initSlider()
方法
mounted:
el
被新创建的vm.$el
替换,并挂载到实例上去之后调用该钩子。
slider.vue
|
|
这儿没有渲染成功,可以思考个问题:我们在mounted 的时候<slot></slot>
里有没有东西?
在渲染recommends
的时候,初始化_getRecommend()
,getRecommend()
是个异步过程,它可能会有几秒的延迟,所以当recommends
还没有获取到的时候也就是<slot></slot>
里没有东西,mounted钩子已经执行了,为了确保<slot></slot>
里有东西再执行mounted,对recommends
进行判断。
dots滚动实现
mounted初始化dots,在data里定义dots实现页面渲染。
定义currentPageIndex
,把滚动到当前页的dot
与currentPageIndex
绑定起来:class="{active: currentPageIndex === index}"
,better-scroll在滚动的时候实现一个事件,所以在初始化slider的时候绑定一个scrollEnd
事件,来实现dot
和currentPageIndex
的绑定
|
|
实现循环播放
|
|
同时初始化slider的时候要判断是否是自动播放,做些逻辑处理
最终效果图:
我们改变窗口大小时会发生图片错乱的错误,所以我们在mounted的时候去监听一个窗口改变的事件适应窗口宽度大小。
|
|
还有个需要注意的一点,我们在切换页面的时候会重新发数据请求,所有元素也会重新渲染,大大增加了性能消耗。我们这里需要缓存整个站点的所有页面,而页面一般一进去都要触发请求的。vue2.0提供了一个keep-alive
组件用来缓存组件,避免多次加载相应的组件,减少性能消耗。
当我们的组件有类似于计时器这种资源的时候,我们在销毁这些资源的时候一定要做清理工作,有利于内存释放。
|
|
歌单详情页面
获取歌单数据
后端接口代理
有时候我们使用jsonp获取资源被拒绝,有host和Referer限制,前端不能直接去修改host,就需要通过后端代理的方式解决问题
后端代理时用到axios,详情见https://github.com/axios/axios
|
|
dev-server.js
|
|
recommends.js
|
|
获取歌单列表及页面展示
|
|
效果如下:
封装scroll滚动组件
|
|
引入到recommend.vue使用组件。
|
|
优化
在scroll组件里传:data="discList"
,为什么不是:data="recommends"
或者diacList和recommends一起传给它?我们知道它们都是异步获取的,原因是轮播图数据获取接口要优先于歌单列表数据接口,当歌单列表获取到数据渲染出来再调scroll.refresh()
,轮播图数据才被渲染出来,这时候高度已经被撑开,也就是说better-scroll能正确计算出高度。
当recommends获取时这个高度不一定会有,因为轮播图的高度是由图片的高度撑开的,也就是说当recommends获取到时item.imgurl
会去请求图片,这是异步过程,我们事先不知道高度,完全是由图片的高度决定的,这里不能用计算属性,使用@load
触发一个事件,一旦有一个图片触发load
,我们就调用loadImage()
方法。
|
|
懒加载
歌单是由很多图片组成的,当我们刷新页面时会发出很多请求,其实刷新只需要展示首屏的图片,而其他图片是当滚动到它们时再加载,使用图片懒加载技术,这里使用vue-lazyload第三方懒加载插件。
|
|
使用方法:在main.js
引入
|
|
把:src="item.imgurl"
改成v-lazy="item.imgurl"
,如图:
better-scroll和fastclick的冲突
我们发现点击slider的时候点不动,是因为better-scroll和fastclick是有冲突的。scroll组件初始化时click默认为true,歌单列表是需要被点击的,所以click设置为true。解决这个冲突问题:
点击slider是点击一张图片,所以可以给图片添加一个属性class="needsclick"
。fastclick监听到img的点击事件发现class是needsclick的话就不会去拦截,这样就不会阻止这个点击。
基础组件loading组件的开发
|
|
引入recommend.vue组件里
|
|
效果: