用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
        width: 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
                    width: 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
        width: 100% 

</style>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM