07.vue.2.x開發(fā)音樂App-歌手詳情頁

github:https://github.com/Ching-Lee/vue-music

1.子路由配置

  • 創(chuàng)建詳情頁組件


  • 在rooter/index.js中添加子路由
  {
      path: '/singer',
      component: Singer,
      children: [
        {
          path: ':singer_id',
          component: SingerDetail
        }
      ]
    },
  • listView是基礎(chǔ)組件,我們?yōu)槊總€li點擊添加事件派發(fā)
<li v-for="(item, index) in (value)" v-bind:key="index" class="singer_item" @click="selectItem(item)">
      <img v-lazy="item.singer_pic" class="singerPic">
      <span class="singer_name">{{item.name}}</span>
</li>
 // 點擊歌手扔役,跳轉(zhuǎn)到該歌手的歌單頁面
    // 這里派發(fā)了事件
    selectItem (item) {
      this.$emit('select', item)
    }
  • 在singer.vue中注冊
<div class="singer" v-if="singerlist.length">
      <listview  v-bind:data=" _singerCountryMap()" @select="selectSinger"></listview>
      <router-view></router-view>
</div>

// 手動跳轉(zhuǎn)

 selectSinger (singer) {
      this.$router.push({
        path: `/singer/${singer.singer_id}`
      })
    }
  • 跳轉(zhuǎn)發(fā)現(xiàn)看不到組件內(nèi)容,去設(shè)置樣式
    這里的z-index要比頭部的大,才能蓋住頭部脊框。
 .singer_detail{
    z-index: 2;
    position:fixed;
    top:0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: white;
  }

2.做漸入漸出的動畫特效

<template>
  <transition name="slide">
    <div class="singer_detail">
      <span>歌手詳情頁</span>
    </div>
  </transition>
</template>
.slide-enter-active, .slide-leave-active {
    transition: all .3s;
  }
  .slide-enter, .slide-leave-to /* .fade-leave-active below version 2.1.8 */
  {
    transform: translate3d(100%, 0, 0);
  }

點擊的時候會有滑屏的效果江耀。

3.使用qq音樂后臺數(shù)據(jù)


這里每次請求15個數(shù)據(jù)屈张,請求參數(shù)中有begin表示請求開始的索引擒权,num是15表示一次15個。
請求參數(shù)中有singerid阁谆,通過singerid返回不同歌手的信息。
音樂信息在list中愉老。


  • 在api添加歌手詳情頁獲取后臺信息的部分


import jsonp from '../assets/js/jsonp'
import {commonParams, options} from './config'

// 獲取歌手詳情頁面相關(guān)數(shù)據(jù)
export function getSingerDetail (singerid) {
  const url = 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg'
  const param = Object.assign({}, commonParams, {
    singerid: singerid,
    uin: 0,
    format: 'json',
    platform: 'h5page',
    needNewCode: 1,
    order: 'listen',
    from: 'h5',
    num: 15,
    begin: 0,
    _: 1528443902453
  })
  return jsonp(url, param, options)
}

  • 在singer_detail.vue中獲取數(shù)據(jù)场绿,賦值給singerDetail
export default {
  data () {
    return {
      singerDetail: null
    }
  },
  computed: {
    getFans () {
      return `粉絲:${(this.singerDetail.fans / 10000).toFixed(2)}萬人`
    },
    getImage () {
      return `http://y.gtimg.cn/music/photo_new/T001R150x150M000${this.singerDetail.singer_mid}.jpg?max_age=2592000`
    }
  },
  created () {
    this._getSinerDetailbyid(this.$route.params.singer_id)
  },
  methods: {
    _getSinerDetailbyid (singerid) {
      getSingerDetail(singerid).then((result) => {
        if (result.code === ERR_OK) {
          this.singerDetail = result.data
        }
      })
    }
  },
}

4.頭部組件開發(fā)singer_detail_header


布局是左邊圖片div,右邊介紹div嫉入,下面按鈕div

<template>
  <div class="detail_top" ref="detailtop">
    <div class="detail_header clearfix">
      <div class="detail_left">
        <img v-bind:src=image />
      </div>
      <div class="detail_right">
        <h2>{{name}}</h2>
        <P class="fans">{{fans}}</P>
        <p class="intruduce">{{intruduce}}</p>
      </div>
    </div>
    <div class="bottom_detail">
      <div class="button">
        <i class="icon-player"></i>
        <span>播放全部</span>
      </div>
    </div>
  </div>
</template>

默認(rèn)屬性:

props: {
    image: {
      type: String,
      default: ''
    },
    name: {
      type: String,
      default: ''
    },
    fans: {
      type: String,
      default: ''
    },
    intruduce: {
      type: String,
      default: ''
    }
  },

css樣式:
圖片和介紹:是一個左邊固定右邊自適應(yīng)的布局焰盗。

左邊固定右邊自適應(yīng)的實現(xiàn)方法:
1)左邊f(xié)loat:left,就會脫離文檔流,然后解決高度塌陷的問題
2)position:absolute,使用絕對定位咒林,左邊的left:0,右邊的right:0
3 ) flex布局熬拒,整體的盒子display:flex,右邊f(xié)lex:1
4 ) grid布局,display:grid,template-grid-column:左邊寬度 auto
5)table布局垫竞,容器寬度設(shè)置為100%澎粟,左右設(shè)置為display:table-cell
這里使用float實現(xiàn)

<style>
  .detail_header {
    background-color:rgba(0, 0, 0, 0.6);
    padding: 1rem;
  }

  .detail_left {
    float: left;
    width: 150px;
    margin-right: 0.5rem;
  }

  .clearfix:after {
    clear: both;
    content: '';
    display: table;
  }

  .detail_right h2 {
    font-size: 1.2rem;
    margin-top: 1rem;
    color: white;
  }

  .detail_right .fans {
    font-size: 1rem;
    margin: 1rem 0;
    color: whitesmoke;
  }

/*設(shè)置三行內(nèi)容蛀序,超出...*/
  .detail_right .intruduce {
    white-space: initial;
    font-size: 0.8rem;
    line-height: 1.2rem;
    color: whitesmoke;
    height:3.6rem;
    overflow: hidden;
    position: relative;
  }
  .detail_right .intruduce:after{
    content:'...';
    font-weight: bold;
    position: absolute;
    bottom: 0;
    right: 0;
  }

  .bottom_detail {
    background-color:rgba(0, 0, 0, 0.6);
    padding-bottom: 1rem;
    text-align: center;
  }
  .button{
    display: inline-block;
    background-color: rgba(0, 0, 0, 0);
    border-radius: 3rem;
    padding: 0.4rem 1.2rem;
    color: white;
    border: 1px orange solid;
  }
/*怎么讓圖片和文字對齊*/
  .button *{
    display:inline-block;
    vertical-align:middle
  }
  .button i{
    font-size: 1.5rem;
    color: orange;
  }

</style>

怎么讓圖片和文字對齊
父元素里的所有元素設(shè)置成內(nèi)斂塊元素,然后居中
.button *{
display:inline-block;
vertical-align:middle
}

怎么設(shè)置三行內(nèi)容活烙,多余的超出:
通過設(shè)置行高+絕對定位
/設(shè)置三行內(nèi)容徐裸,超出.../
.detail_right .intruduce {
line-height: 1.2rem;
/height是line-height的3倍/
height:3.6rem;
overflow: hidden;
position: relative;
}
.detail_right .intruduce:after{
content:'...';
font-weight: bold;
position: absolute;
bottom: 0;
right: 0;
}

  • 然后去設(shè)置背景圖片
 mounted () {
    this._setBackgroundPic()
  },
  methods: {
    _setBackgroundPic () {
      let target = this.$refs.detailtop
      target.style.backgroundImage = `url(${this.image})`
      target.style.backgroundSize = '100% auto'
    }
  }
  • 父組件中調(diào)用傳遞屬性
<template>
  <transition name="slide">
      <div class="singer_detail" v-if="singerDetail" >
        <singer-detail-header v-bind:image=getImage v-bind:name="singerDetail.singer_name" v-bind:fans="getFans" v-bind:intruduce="singerDetail.SingerDesc"></singer-detail-header>
        <p class="total_song">歌曲 共{{singerDetail.total}}首</p>
      </div>
  </transition>
</template>

5.music-list組件開發(fā)


<template>
  <div>
    <ul class="music_list">
      <li v-for="(item, index) in list" v-bind:key="index">
        <h2>{{item.musicData.songname}}</h2>
        <p>{{item.musicData.singer[0].name}}   {{item.musicData.albumdesc}}</p>
      </li>
    </ul>
  </div>
</template>

<script type="text/ecmascript-6">
export default{
  props: {
    list: {
      type: Array,
      default: null
    }
  }
}
</script>

<style>
  .music_list li{
    padding: 1rem;
    border-bottom: 1px solid whitesmoke;
  }
  .music_list li h2{
    font-size: 1rem;
  }
  .music_list li p{
    font-size: 0.8rem;
    margin-top: 10px;
    color: orange;
    line-height: 1rem;
  }
</style>

6.讓music-list組件能夠滑動

使用vue-iscroll-view,參考文檔
https://dafrok.github.io/vue-iscroll-view/

  • 首先安裝



  • 在main.js中use
import IScrollView from 'vue-iscroll-view'
import IScroll from 'iscroll'
Vue.use(IScrollView, IScroll)
  • music.list中添加
<template>
  <iscroll-view ref='scrollView' class='scroll_view' :options="{preventDefault: true}">
    <ul class="music_list">
      <li v-for="(item, index) in list" v-bind:key="index">
        <h2>{{item.musicData.songname}}</h2>
        <p>{{item.musicData.singer[0].name}}   {{item.musicData.albumdesc}}</p>
      </li>
    </ul>
  </iscroll-view>
</template>
 mounted () {
    this.$refs.scrollView.refresh()
  }
 .scroll_view{
    touch-action:none;
    position: fixed;
    left: 0;
    right: 0;
    top: 280px;
    bottom: 0;
    overflow: hidden;
  }

7.加載更多組件

  • 實現(xiàn)loadMore功能
    hasmore屬性:表示是否還有數(shù)據(jù)
    number屬性:number表示已經(jīng)加載的數(shù)據(jù)數(shù)量啸盏,當(dāng)大于全部數(shù)量時重贺,hasMore就是false
    list:存儲數(shù)據(jù)的列表
    isLoading: 正在加載
    begin: 發(fā)起請求時的請求參數(shù),開始的索引
    singer_detail中添加更改屬性和方法
export default {
  data () {
    return {
      singerDetail: null,
      begin: 0,
      isLoading: false,
      list: [],
      number: 0, // number表示已經(jīng)加載的數(shù)據(jù)數(shù)量回懦,當(dāng)大于全部數(shù)量時气笙,hasMore就是false
      hasMore: true, // 表示是否還有數(shù)據(jù)
      showMoreDec: false
    }
  },
methods: {
    _getSinerDetailbyid (singerid, begin) {
      console.log(singerid)
      getSingerDetail(singerid, begin).then((result) => {
        if (result.code === ERR_OK) {
          this.singerDetail = result.data
          //在用push方法時報錯
          this.list = this.list.concat(result.data.list)
          this.number = this.number + result.data.list.length
          if (this.number >= result.data.total) {
            this.hasMore = false
          }
          this.isLoading = false
        }
      })
    },
    _loadFn () {
      if (this.hasMore) {
        this.isLoading = true
        this.begin = this.begin + 15
        this._getSinerDetailbyid(this.$route.params.singer_id, this.begin)
      }
    },
  • 調(diào)用musiclist的時候傳遞屬性
    @loadmore是接收觸發(fā)
<music-list v-bind:list="list" @loadmore="_loadFn" v-bind:hasMore="hasMore"></music-list>

misiclist中調(diào)用load-more組件,完成分發(fā)

 <load-more @loadmore="dispachload()" v-bind:isLoading="isLoading" v-bind:hasMore="hasMore"></load-more>
export default {
  props: {
    list: {
      type: Array,
      default: null
    },
    isLoading: {
      type: Boolean,
      default: false
    },
    hasMore: {
      type: Boolean,
      default: true
    }
  },
 components: {
    'load-more': LoadMore
  },
  methods: {
    dispachload () {
      this.$emit('loadmore')
    },
  • loadMore組件
    如果有更多怯晕,并且當(dāng)前沒有在加載健民,就顯示加載更多。當(dāng)點擊時就觸發(fā)事件傳遞贫贝。
    沒有更多秉犹,就顯示我是有底線的。
<template>
  <div v-if='hasMore' ref="loaddiv" v-show="!isLoading" v-on:click="dispachload()" class="loaddiv">上拉加載更多</div>
  <div class="loaddiv" v-else>我是有底線的</div>
</template>

<script type="text/ecmascript-6">
export default{
  props: {
    isLoading: {
      type: Boolean,
      default: false
    },
    hasMore: {
      type: Boolean,
      default: true
    }
  },
  methods: {
    dispachload () {
      this.$emit('loadmore')
    }
  }
}

</script>

<style>
 .loaddiv{
    text-align: center;
    line-height: 1rem;
  }
</style>

  • 這時候會發(fā)現(xiàn)點擊時稚晚,請求到了新的數(shù)據(jù)崇堵,但是滾動條不能向下滾動。
    我們需要在music_list中添加對list列表改變進(jìn)行watch
 watch: {
    list: function () {
      this.$refs.scrollView.refresh()
    }
  },
  • 添加上滑自動加載
 methods: {
    dispachload () {
      this.$emit('loadmore')
    },
    /* pullDown () {
      console.log('pullDown')
    }, */
    pullUp () {
      this.dispachload()
    }
  }

8.彈出歌手詳細(xì)介紹的模態(tài)框


一個大的div客燕,設(shè)置成絕對定位鸳劳,top:0,left:0,right:0,bottom:0,設(shè)置背景顏色和透明度
里面包裹著一個中間顯示的div,設(shè)置背景為白色也搓。

<template>
  <transition name="slide">
      <div class="singer_detail" v-if="singerDetail" >
        <singer-detail-header @alert="_alertfn" v-bind:image=getImage v-bind:name="singerDetail.singer_name" v-bind:fans="getFans" v-bind:intruduce="singerDetail.SingerDesc"></singer-detail-header>
        <p class="total_song">歌曲 共{{singerDetail.total}}首</p>
        <music-list v-bind:list="list" @loadmore="_loadFn" v-bind:hasMore="hasMore"></music-list>
        <div class="back" v-show="showMoreDec">
          <div id="moredec">
            <div id="dectext">{{singerDetail.SingerDesc}}</div>
            <div id="closebutton" v-on:click="_closefn()">關(guān)閉</div>
          </div>
        </div>
      </div>
  </transition>
</template>

通過屬性showMoreDec控制顯示與否赏廓,當(dāng)點擊singer-detail-header組件中的介紹時,觸發(fā)分發(fā)alert事件給父組件sing_detail傍妒,在父組件中改變屬性showMoreDec值為true

 data () {
showMoreDec: false
}
 methods: {16
 _alertfn () {
      this.showMoreDec = true
    },
    _closefn () {
      this.showMoreDec = false
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幔摸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子颤练,更是在濱河造成了極大的恐慌既忆,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嗦玖,死亡現(xiàn)場離奇詭異患雇,居然都是意外死亡,警方通過查閱死者的電腦和手機宇挫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門苛吱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人器瘪,你說我怎么就攤上這事翠储』嫜悖” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵彰亥,是天一觀的道長咧七。 經(jīng)常有香客問我,道長任斋,這世上最難降的妖魔是什么继阻? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮废酷,結(jié)果婚禮上瘟檩,老公的妹妹穿的比我還像新娘。我一直安慰自己澈蟆,他們只是感情好墨辛,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著趴俘,像睡著了一般睹簇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寥闪,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天太惠,我揣著相機與錄音,去河邊找鬼疲憋。 笑死凿渊,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缚柳。 我是一名探鬼主播埃脏,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼秋忙!你這毒婦竟也來了彩掐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤翰绊,失蹤者是張志新(化名)和其女友劉穎佩谷,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體监嗜,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年抡谐,在試婚紗的時候發(fā)現(xiàn)自己被綠了裁奇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡麦撵,死狀恐怖刽肠,靈堂內(nèi)的尸體忽然破棺而出溃肪,到底是詐尸還是另有隱情,我是刑警寧澤音五,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布惫撰,位于F島的核電站,受9級特大地震影響躺涝,放射性物質(zhì)發(fā)生泄漏厨钻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一坚嗜、第九天 我趴在偏房一處隱蔽的房頂上張望夯膀。 院中可真熱鬧,春花似錦苍蔬、人聲如沸诱建。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俺猿。三九已至,卻和暖如春格仲,著一層夾襖步出監(jiān)牢的瞬間押袍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工抓狭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留伯病,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓否过,卻偏偏與公主長得像午笛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子苗桂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容

  • github:https://github.com/Ching-Lee/vue-music 1.分析后臺數(shù)據(jù) 從Q...
    Ching_Lee閱讀 1,345評論 5 0
  • awesome-github-vue 是由OpenDigg[https://blog.csdn.net/opend...
    我是七月閱讀 2,408評論 0 20
  • 目錄 UI組件 開發(fā)框架 實用庫 服務(wù)端 輔助工具 應(yīng)用實例 Demo示例 UI組件 element ★31142...
    吳佳浩閱讀 10,947評論 1 61
  • 中秋剛過药磺。 中華民族有這么幾個傳統(tǒng)節(jié)日,像端午煤伟、重陽癌佩、中秋、春節(jié)便锨、元宵節(jié)等围辙,總是與闔家歡樂聯(lián)系在一起》虐福可能從小就未...
    載酒閱讀 195評論 0 0
  • “魔祖姚建,這個東伯雪鷹是和你來自同一個宇宙吧,這個小家伙挺厲害啊吱殉,來太虛天宮還沒多久掸冤,竟然就能在太虛天宮內(nèi)真神弟子中...
    im喵小姐閱讀 428評論 0 0