• 用Vue来实现音乐播放器(十六):滚动列表的实现


    滚动列表是一个基础组件  他是基于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>
  • 相关阅读:
    错排问题
    用GDAL/OGR去读shapefile
    聊聊MyBatis缓存机制
    一份平民化的应用性能优化检查列表(完整篇)--转
    微服务实战(七):从单体式架构迁移到微服务架构
    微服务实战(六):选择微服务部署策略
    微服务实战(五):微服务的事件驱动数据管理
    微服务实战(四):服务发现的可行方案以及实践案例
    微服务实战(三):深入微服务架构的进程间通信
    微服务实战(一):微服务架构的优势与不足
  • 原文地址:https://www.cnblogs.com/catbrother/p/9180917.html
Copyright © 2020-2023  润新知