歌手页面类似于通讯录,相应的功能有:获取数据、排序、快速切换、左右联动、滚动等

1.获取数据

在api/singer.js中导入JSONP方法,获取singers,在singer.vue中

created() {this._getSingerList()
},
_getSingerList() {getSingerList().then((res) => {if (res.code === ERR_OK) {console.log(res.data.list)//序列化数据this.singers = this._normallizeSinger(res.data.list)}})
},

得到的数据结构入如下:

2.数据序列化

这样结构不符合我们的需求,需要序列化;
在序列化时候,相应的分类中push是singer实例,目的是生成avatar

_normallizeSinger(list) {
//1.定义一个maplet map = {hot: {title: HOT_NAME,items: []}}
//2.将前 HOT_SINGER_LEN = 10个放入‘热’分类中      list.forEach((item, index) => {if (index < HOT_SINGER_LEN) {map.hot.items.push(new Singer({id: item.Fsinger_mid,name: item.Fsinger_name}))}
//3.其他的按照Findex分类const key = item.Findex    //A B C D...if (!map[key]) {map[key] = {title: key,items: []}}map[key].items.push(new Singer({id: item.Fsinger_mid,name: item.Fsinger_name}))})
//4.为了得到有序列表,我们需要排序map,定义一个hot一个其他retlet hot = []let ret = []for (let key in map) {let val = map[key]//如果是A B C等在push到ret其他if (val.title.match(/[a-zA-Z]/)) {ret.push(val)//如果是‘热’HOT_NAME则放入hot} else if (val.title === HOT_NAME) {hot.push(val)}}
//5.对其他ret进行排序ret.sort((a, b) => {return a.title.charCodeAt(0) - b.title.charCodeAt(0)})
//6.合并两个数组return hot.concat(ret)},

3.singer实例化

在序列化时候,相应的分类中push是singer实例,目的是生成avatar

export default class Singer {constructor ({id, name}) {this.id = idthis.name = namethis.avatar = `http://y.gtimg.cn/music/photo_new/T001R150x150M000${id}.jpg?max_age=2592000`}
}

4.样式

这里要进行滚动,所以使用了scroll.vue组件

5.数据序列化后传入list-vue

<div class="singer" ref="singer"><list-view ref="list" @select="selectSinger" :data="singers"></list-view><router-view></router-view>
</div>

通过:data传入this.singers,同时,emit事件selectSinger,导航至singer-detail.vue中

selectSinger(singer) {this.$router.push({path: `/singer/${singer.id}`})//同时,将singer的信息放入vuex中this.setSinger(singer)
},

6.list-vue 右→左联动

将this.singer传入list-vue中,数据的渲染左侧歌手列表,右侧导航索引

6.1右侧导航:索引数据

利用计算属性,获取右侧导航数据,然后渲染

 computed: {shortcutList() {return this.data.map((group) => {return group.title.substr(0, 1)})},
......},

6.2右侧导航:定义touch事件

 <!--touchumove.stop.prevent 阻止事件冒泡、默认行为(浏览器滚动)--><div class="list-shortcut" @touchstart="onShortCutTouchStart" @touchmove.stop.prevent="onShortCutTouchMove"><ul><li :key="item.title" v-for="(item,index) in shortcutList":data-index="index"   //自定义属性data-index用来获取当前li的索引值:class="{'current':currentIndex === index}"class="item">{{item}}</li></ul></div>

牵涉到滚动事件,同样的思路:在created中创建this.touch = {}

onShortCutTouchStart(e) {let anchorIndex = getData(e.target, 'index') //getData公共方法,获取当前点击的li的索引let firstTouch = e.touches[0]this.touch.y1 = firstTouch.pageYthis.touch.anchorIndex = anchorIndexthis._scrollTo(anchorIndex)
},
onShortCutTouchMove(e) {let firstTouch = e.touches[0]this.touch.y2 = firstTouch.pageY
//获取相应的滑动了几个li的高度ANCHER_HEIGHT=18let delta = (this.touch.y2 - this.touch.y1) / ANCHER_HEIGHT | 0
//根据计算的滑动几个li数量,得出索引值let anchorIndex = parseInt(this.touch.anchorIndex) + delta
//左侧根绝索引值进行滚动this._scrollTo(anchorIndex)
},
_scrollTo(index) {//点击最顶部或者底部的时候,因为时间在div上,而div{padding:20px 0},所以,这个时候没有点击到li元素,也就无法获取index,因此index:nullif (!index && index !== 0) {return}//滑动到最顶部或者底部if (index < 0) {index = 0} else if (index > this.listHeight.length - 2) {//this.listHeight.length - 2:正常情况index=this.listHeight.length-1,这里是因为在初始化this.listHeight的方法_caculateHeight中push了一个height = 0index = this.listHeight.length - 2}//0:是表示缓动动画时间 这里表示立刻滚动没有动画//调用scroll组件的方法this.$refs.listview.scrollToElement(this.$refs.listGroup[index], 0)//scrollY:左→右联动的滑动距离this.scrollY = -this.listHeight[index]
},

7. 左→右联动

7.1 组件有数据的时候就开始计算高度

当传入数据的时候,开始计算高度:data="singers"
同touch一样在created中定义this.listHeight=[]共享不用双向绑定的数据

watch: {data() {setTimeout(() => {this._caculateHeight()}, 20)},
····
}
####7.2 将左侧列表高度叠加放入一个数组
methods:{_caculateHeight() {this.listHeight = []const list = this.$refs.listGrouplet height = 0this.listHeight.push(height)for (let i = 0; i < list.length; i++) {let item = list[i]height += item.clientHeightthis.listHeight.push(height)}}
}

7.3 监听左侧滚动

牵涉到滚动,我们就需要使用scroll组件

在methods中定义scroll事件

scroll(pos) {//pos.y 滑动时负数,到顶部的时候,向下滑动空白回弹,这时是正数this.scrollY = pos.y
},

在watch中观察scrollY

 watch: {
·······scrollY(newY) {const listHeight = this.listHeight//到顶部的时候,向下滑动空白回弹,这时是正数,newY>0if (newY > 0) {//this.currentIndex给左侧导航高亮 this.currentIndex = 0return}//滚动至中部for (let i = 0; i < listHeight.length - 1; i++) {let height1 = listHeight[i]let height2 = listHeight[i + 1]if (-newY >= height1 && -newY < height2) {//滚动左侧,从而找到相应的索引,右侧导航高亮this.currentIndex = i//比如是A上限距离顶部的距离 newY是个负值,相当于减this.diff = height2 + newYreturn}}//滚动至底部,且-newY大于最后一个元素的上限  因为listHeight首先push一个height=0this.currentIndex = listHeight.length - 2},
······

8. 左侧列表的过渡效果


.list-fixedposition: absolutetop: 0left: 0width: 100%.fixed-titleheight: 30pxline-height: 30pxpadding-left: 20pxfont-size: $font-size-smallcolor: $color-text-lbackground: $color-highlight-background

在data中定义{diff:-1}
在watch中观察diff

diff(newVal) {//newVal - TITLE_HEIGHT为负值,因为transform往上是负值//当newVal<TITLE_HEIGHT(title的高度30)的时候,fixedTop != 0 这个时候继续执行let fixedTop = (newVal > 0 && newVal < TITLE_HEIGHT) ? newVal - TITLE_HEIGHT : 0if (this.fixedTop === fixedTop) {return}this.fixedTop = fixedTop//继续执行,fixed上移this.$refs.fixed.style.transform = `translate3d(0, ${fixedTop}px, 0)`}

同时在scrollY的watch中计算diff

watch: {
·······scrollY(newY) {
......for (let i = 0; i < listHeight.length - 1; i++) {let height2 = listHeight[i + 1]if (-newY >= height1 && -newY < height2) {
......this.diff = height2 + newY}}},
······

vue_music:歌手singer.vue页面相关推荐

  1. singer页面点击歌手singer是跳转到singer-detail的设置

    1.创建components/singer-detail/singer-detail.vue 2.配置动态路由: 1 { 2 path: ':id', 3 name:'singer-detail', ...

  2. php加载外部html,VUE页面加载外部HTML实例详解

    前后端分离,后端提供了接口.但有一部分数据,比较产品说明文件,是存在其他的服务器上的.所以,在页面显示的时候,如果以页面内嵌的形式显示这个说明文件.需要搞点事情以达到想要的效果.本文主要和大家介绍了V ...

  3. vue 页面闪烁的问题_vue页面加载闪烁问题的解决方法

    v-if 和 v-show 的区别 v-if只会在满足条件时才会编译,而v-show不管是否满足条件始终会编译,v-show的显示与隐藏只是简单的切换CSS的display属性. 也就是说,在使用v- ...

  4. vue页面跳转后返回原页面初始位置

    vue页面跳转到新页面之后,再由新页面返回到原页面时候若想返回调出原页面的初始位置,怎么来解决这个问题呢?首先我们应该在跳出页面时候记录下跳出的scrollY,返回原页面的时候在设置返回位置为记录下的 ...

  5. SAP Cloud Application Programming bookshop 例子 Vue页面不能正常显示的原因分析

    我在本地用cds run 命令启动 SAP Cloud Application Programming 应用后,访问如下 url: http://localhost:4004/vue/index.ht ...

  6. Vue页面骨架屏(一)

    在开发webapp的时候总是会受到首屏加载时间过长的影响,主流的解决方法是在载入完成之前显示loading图效果,而一些大公司会配置一套服务端渲染的架构来解决这个问题.考虑到ssr所要解决的一系列问题 ...

  7. Vue 页面如何利用生命周期函数监听用户预览时长

    最近的业务中涉及到这样一个需求,在线培训的系统需要知道用户对某个在线预览的页面追踪用户的预览时长.初步我们首先想到借助 Vue 页面的生命周期函数 mounted 和 destroyed,分别在其中加 ...

  8. Vue 页面如何监听用户预览时间

    最近的业务中涉及到这样一个需求,在线培训的系统需要知道用户对某个在线预览的页面追踪用户的预览时长.初步我们首先想到借助 Vue 页面的生命周期函数 mounted 和 destroyed,分别在其中加 ...

  9. Vue页面跳转后不显示问题

    Vue页面跳转后不显示问题 必须要添加 path前面要有/

最新文章

  1. python 爬虫 爬取序列博客文章列表
  2. xcode7.1 安装不了Alcatraz怎么办.看这里
  3. opencv中的椭圆拟合
  4. css 水平垂直居中那些事
  5. 在Ubuntu 16.04上增加Swap分区
  6. 合成未来宝宝照片_赵丽颖冯绍峰的宝宝会长啥样?网友把两人照片合成,却长得很像她...
  7. docker安装和启动zookeeper,数据导入及导出
  8. python主线程执行_python主线程与子线程的结束顺序实例解析
  9. 诛仙2怎样修改服务器时间同步,《诛仙2》2月22日更新公告
  10. BPF BTF 详细介绍
  11. 曾经以为老去是很遥远的事情
  12. html凹凸感设置,想让VRAY渲染的图有点凹凸效果怎么做?
  13. tkinterQQ音乐与音频可视化
  14. 结合GUI可视化发送QQ消息 —— 2022/2/11
  15. librosa.effects.split
  16. 可信验证与TPCM技术
  17. 用金蝶kis录入数量初始数据的方法
  18. img标签的alt属性简单介绍
  19. 2020年IEEE Fellow刚刚揭榜!超70名华人入选
  20. 细说会声会影各版本安装的配置要求及注意事项

热门文章

  1. TIL:创建Java线程的两种方法
  2. 指令系统——CISC和RISC
  3. 从万达百货到家乐福中国,苏宁如何快速消化“大块头”?
  4. WIFI信号放大增强器(中继器)中继成功后怎么改名字
  5. VisionPro和Halcon 的详细对比
  6. 【渝粤教育】电大中专计算机职业素养 (2)作业 题库
  7. 老师上课也能涨粉?胖超说艺考坐拥千万粉丝靠什么?
  8. x86 smbus 下挂eeprom不能写问题
  9. 域名解析不生效的原因及排查方法
  10. 某人力资源Saas软件公司面试经历