滚动列表是一个基础组件 他是基于scroll组件实现的
在base文件夹下面创建一个list-view文件夹 里面有list-view.vue组件
<template> <!-- 当父组件传递给子组件的数据发生变化的时候 scroll可以监听到此时高度会发生变化 --> <!-- 子组件这里的:data和props里面的data相对于 --> <!-- 父传子的时候 data是对应的props里面的值 --> <scroll class="listview" :daaaaa="data" > <!-- scroll插件作用于第一个子元素 ul--> <!-- 父元素传来的data数组的形式是[{title:"热门",items:Array(3)},{title:"A",items:Array[4]}] --> <!-- 外层的ul下的li 代表每一个title对应的items --> <ul> <!--这里面的每一个li 是代表一个组别 比如热门歌手组别 姓氏为A的组别 姓氏为B的组别等等 --> <li v-for="(group,index) in data" class="list-group" :key="index"> <h2 class="list-group-title">{{group.title}}</h2> <!-- 内层的ul下的li 代表每一个title对应的items下的Array里面的内容 --> <ul> <!-- 这里面的每一个li代表每个组别里面的每一位歌手 --> <li v-for="(item,index) in group.items" class="list-group-item" :key="index"> <img v-lazy="item.avatar" class="avatar"> <span class="name">{{item.name}}</span> </li> </ul> </li> </ul> </scroll> </template> <script> //因为是滚动列表 所以导入Scroll组件 import Scroll from '../scroll/scroll.vue' export default { // 接受父盒子传入的数据 props:{ data:{ type:Array, default:[] } }, components:{ Scroll } } </script> <style lang="stylus" scoped> @import '../../common/stylus/variable.styl' .listview position: relative 100% height: 100% overflow: hidden background: $color-background .list-group padding-bottom: 30px .list-group-title height: 30px line-height: 30px padding-left: 20px font-size: $font-size-small color: $color-text-l background: $color-highlight-background .list-group-item display: flex align-items: center padding: 20px 0 0 30px .avatar 50px height: 50px border-radius: 50% .name margin-left: 20px color: $color-text-l font-size: $font-size-medium </style>
在singer.vue中
<template>
<!-- better-scroll的滚动条件是:父容器的高度是固定的
子容器要撑开他 所以这个fixed布局是为了固定父容器的高度
-->
<div class="singer">
<!-- 这个singer类就相当于是scroll的父类元素 -->
<!-- 给子组件传递值 singers -->
<!-- 给data加上:data 说明后面跟的singers是变量 -->
<!-- 父组件真正传递的值是singers -->
<list-view :data="singers"></list-view>
</div>
</template>
<script>
import ListView from '../../base/listview/listview.vue'
import {getSingerList} from '../../api/singer.js'
import {ERR_OK} from '../../api/config.js'
import Singer from '../../common/js/singer.js'
const HOT_NAME="热门" //由于页面布局是热门 然后下面是数组
// 将取到的this.singer数据中的前10条定义为热门数据
const HOT_SINGER_LEN=10
export default {
data(){
return {
singers:[]
}
},
created(){
this._getSingerList()
},
methods:{
_getSingerList(){
getSingerList().then((res)=>{
if(res.code===ERR_OK){
// console.log(res.data)
this.singers=this._normalizeSinger(res.data.list)
console.log(this._normalizeSinger(res.data.list))
}
})//虽然这个方法可以返回数据 但并不是我们想要的
//按照需求 我们应该得到热门歌手数据 和 可以根据歌手的姓氏
//来查找到该歌手 于是我们在写一个方法来操作这个方法得到的数据
},
_normalizeSinger(list) {
let map = {
hot: {
title: HOT_NAME,
items: []
}
}
list.forEach((item, index) => {
if (index < HOT_SINGER_LEN) {
map.hot.items.push(new Singer({
name: item.Fsinger_name,
id: item.Fsinger_mid
}))
}
//将姓氏聚类
const key = item.Findex
if (!map[key]) {//判断此时map对象里面有没有key这个键
//如果没有的话 就给对象添加这个键值对
map[key] = {
title: key,
items: []
}
}
//举例:如果此时key为A
//此时map只有一个键为hot 所以我们给map对象添加一个键为A 这个键A对应的值为{title:"A",items:[]}
map[key].items.push(new Singer({
name: item.Fsinger_name,
id: item.Fsinger_mid
}))
//再执行push操作 给键A对应的键值中的items push值
// 此时的map为 map={hot:{title:"热门",items:[]},A:{title:'A',items:[刚才新添加的值 即此时遍历到的item]}}
})
// console.log('map......',map)
// 为了得到有序列表 处理map
let hot=[]
let ret=[]
for(let key in map){//map是对象也可以用for in 遍历来做
let val=map[key] //这里是map对象的key键对应的键值
if(val.title.match(/[a-zA-Z]/)){
ret.push(val)
}else if(val.title==="热门"){
hot.push(val)
}
}
//为了要让ret里面的数据是按字母升序排列 那么我们可以
ret.sort((a,b)=>{
// 因为ret数组中的数是对象 所以要比较两个对象的title的首字母的大小来判断顺序
return a.title.charCodeAt(0)-b.title.charCodeAt(0)
})
return hot.concat(ret);
}
},
components:{
ListView
}
}
</script>
<style lang="stylus" scoped>
.singer
position: fixed
top: 88px
bottom: 0
100%
</style>