vue_music:歌手詳情頁

在singer.vue中,點擊某一歌手,根據路由跳轉到singer-detail.vue
在vue-muscie:singer.vue頁面的5.數據序列化後傳入list-vue中相關邏輯 vue

selectSinger(singer) {
  //導航至singer-detail.vue頁面
  this.$router.push({
    path: `/singer/${singer.id}`
  })
  //同時,將singer的信息放入vuex中
  this.setSinger(singer)
},

因爲singer-detail.vue頁面具備共同性,所以封裝成一個組件music-list.vueweb

1.singer-detail.vue

這個組件比較簡單,一個殼子,獲取數據傳入組件
圖片描述vuex

1.1獲取數據

_getDetail() {
  //若是在歌手詳情頁面刷新,沒法獲取singer.id,則直接返回歌手列表頁面
  if (!this.singer.id) {
    this.$router.push('/singer')
  }
  getSingerDetail(this.singer.id).then((res) => {
    if (res.code === ERR_OK) {
      this.songs = this._normallizeSongs(res.data.list)
    }
  })
},

1.2 獲取的數據序列化

_normallizeSongs(list) {
  let ret = []
  list.forEach((item) => {
    let {musicData} = item
    if (musicData.songid && musicData.albummid) {
          ret.push(createSong(musicData))
    }
  })
  return ret
}

這裏使用createSong,建立一個song實例
圖片描述瀏覽器

2.music-list.vue

這個組件需求:app

  1. 背景圖 bgImage
  2. 標題title
  3. 歌手詳情數據songs

2.1 頁面

圖片描述
組件須要接收的數據props函數

props: {
    bgImage: {  //背景圖片
      type: String,
      default: ''
    },
    songs: {   //歌手詳情數據songs
      type: Array,
      default: () => []
    },
    title: {   //標題title
      type: String,
      default: ''
    },
}

背景圖片的利用:style 和 computedthis

<div class="bg-image" :style="bgStyle" ref="bgImage">

computed: {
    bgStyle() {
      return `background-image:url(${this.bgImage})`
    }
},

2.2 滾動列表

根據歌手查詢到歌曲列表,須要滾動scroll.vueurl

<div class="bg-layer" ref="layer"></div>
      <scroll
        @scroll="scroll"               //須要派發滾動位置,觸發的事件
        :probe-type="probeType"        //不須要截流
        :listen-scroll="listenScroll"  //派發滾動位置
        :data="songs"                  //接收數據,初始化scroll
        class="list"
        ref="list">
        <div class="song-list-wrapper">
          <song-list @select="selectItem" :songs="songs" :rank="rank"></song-list>
        </div>
      </scroll>

2.3 滾動需求

  • 爲了能讓他向上滾動,初始化的時候列表設置top值
mounted() {
//背景圖圖片的高度
    this.imageHeight = this.$refs.bgImage.clientHeight
//滾動的邊界:滾動到此 背景圖片 ——(減去) 頂部title的高度 
    this.minTranslateY = -this.imageHeight + RESERVED_HEIGHT(40)
//初始化的時候列表設置top值:爲了列表向上滾動而進行traslate3d
    this.$refs.list.$el.style.top = `${this.$refs.bgImage.clientHeight}px`
  },
  • 左側滾動

觸發滾動事件spa

scroll(pos) {
  this.scrollY = pos.y
},

監聽滾動位置scrollY3d

watch: {
    scrollY(newY) {
      //往上滑動newY是負數    translateY往上移動是負數
      //沒有滑到臨界值的時候translateY=newY  滑動頂部40的時候translateY=this.minTranslateY
      let translateY = Math.max(this.minTranslateY, newY)
      
      this.$refs.layer.style['transform'] = `translate3d(0, ${translateY}px,0)`
      this.$refs.layer.style['webkitTransform'] = `translate3d(0, ${translateY}px,0)`
      let zIndex = 0
      //縮放
      let scale = 1
      //比例
      let perscent = Math.abs(newY / this.imageHeight)
      //高斯模糊
      let blur = 0
      //下拉的時候
      if (newY > 0) {
        scale = 1 + perscent
        zIndex = 10
      } else {
        //上滑的時候:高斯模糊
        blur = Math.min(20 * perscent, 20)
      }

      if (newY < this.minTranslateY) {
//上滑 `過` 臨界值的時候,背景圖片相應改變,按鈕消失
        zIndex = 10
        this.$refs.bgImage.style.paddingTop = 0
        this.$refs.bgImage.style.height = `${RESERVED_HEIGHT}px`
     
        this.$refs.playButton.style.display = 'none'
      } else {
//下滑 `未過` 臨界值的時候
        this.$refs.bgImage.style.paddingTop = '70%'
        this.$refs.bgImage.style.height = '0'

        this.$refs.playButton.style.display = ''
      }
      this.$refs.bgImage.style.zIndex = zIndex
      
      //爲何從頂部顯示scale縮放:由於下面的CSS  .bg-image中  transform-origin: top
      //下拉的時候放大效果
      this.$refs.bgImage.style[transform] = `scale(${scale})`

      //高斯模糊  IOS
      this.$refs.bgImage.style[backdrop] = `blur(${blur}px)`
    }
  },

3.瀏覽器前綴

在使用transform以及back-drop的時候,須要根絕瀏覽器添加一些前綴,封裝成方法調用

let elementStyle = document.createElement('div').style
//自執行函數:瀏覽器兼容的前綴
let vender = (() => {
    const tranforNames = {
        webkit:'webkitTransfrom',
        Moz:'MozTransfrom',
        O:'OTransfrom',
        ms:'msTransfrom',
        standard:'standard'
    }
    for(let key in transforNames){
        if(elementStyle[transfromNames[key]] !== undefined){
            return key
        }
    }
    return false
})()
export function prefixStyle(style){
    if(vendor === false){
        return false
    }
    if(ventor === 'standard'){
        return style
    }
    
    return vendor + style.charAt(0).toUpperCase() + style.substr(1)
}

在music-list.vue中引入
const transform = prefixStyle('transform')

4.song-list.vue

列表很常見,封裝成組件song-list.vue
傳入songs數據
功能:展現數據,傳出點擊的數據

<div class="song-list">
    <ul>
      <li @click="selectItem(song,index)" :key="song.id" v-for="(song,index) in songs" class="item">
        <div class="content">
          <h2 class="name">{{song.name}}</h2>
          <p class="desc">{{getDesc(song)}}</p>
        </div>
      </li>
    </ul>
  </div>
methods:{
    getDesc(song) {
      return `${song.singer} . ${song.album}`
    },
    selectItem(item, index) {
      this.$emit('select', item, index)
    },
}
相關文章
相關標籤/搜索