1. 程式人生 > >Vue開發音樂移動端實戰(1) —header頭部元件開發和swiper輪播圖開發 以及利用JSONP獲取QQ音樂輪播圖資料

Vue開發音樂移動端實戰(1) —header頭部元件開發和swiper輪播圖開發 以及利用JSONP獲取QQ音樂輪播圖資料

首先做專案配置 安裝babel-polyfill這是es6語法轉化(在路由中引用的)

babel-fastclick 去除移動端click點選的300毫秒延遲(在路由中index.js下寫入)

import fastclick from 'fastclick'//引用
fastclick.attach(document.body)//掛載到body元素上

better-scroll 滾動外掛(元件中引用)

import BScroll from 'better-scroll'

vue-awesome-swiper 針對Vue的swiper輪播圖外掛(main.js中)

import VueAwesomeSwiper from 'vue-awesome-swiper' //引用js
import 'swiper/dist/css/swiper.css' //引用輪播CSS檔案
Vue.use(VueAwesomeSwiper) //Vue全域性去使用

這兩個元件相對比較簡單!

1.頂部導航欄主要利用Vue-router 2.0 的二級路由實現的區域性變化效果.

路由程式碼:

/**
* recommend 推薦頁面
* search 搜尋頁面
* singer 歌手頁面
* rank 排行頁面
*/
export default new Router({
    routes: [{
        path: '/',
        name: 'entrance',
        component: entrance,
        redirect: '/recommend',
        children: [{
                path: '/recommend',
                component: Recommend
            },
            {
                path: '/search',
                component: Search
            },
            {
                path: '/singer',
                component: Singer
            },
            {
                path: '/rank',
                component: Rank
            }
        ]
    }]
})

children:[]-------在主頁面entrance中的子路由四個頁面 要在頂部導航欄下方加上

<router-view></router-view>

2.頂部導航欄佈局方式:巧妙利用flex彈性盒子佈局適應移動端大小

核心css:

.tab {
  margin-bottom:1rem;
  margin-top:1rem;
  display:flex;
  height:1.5rem;
  -webkit-justify-content:space-around;
  -moz-justify-content:space-around;
  justify-content:space-around; //兩邊空隙均勻分佈
}

3.抓取QQ音樂資料 - 重要(如何jsonp獲取資料)

①.jsonp是什麼?jsonp是目前可以跨域的(基本上標籤帶有src屬性的都是可以不受任何訪問限制),且要動態生成script標籤在ajax無法跨域的情況下可以使用jsonp進行請求但它跟ajax是不一樣的..jsonp利用url連結進行請求傳送和呼叫回撥函式(callblack)使用資料。

例如下面連結:

https://c.y.qq.com/splcloud/fcgi-bin/p.fcg?g_tk=1671758421&format=jsonp&jsonpCallback=jsonp1

除去前面https://c.y.qq.com/splcloud/fcgi-bin/p.fcg

只剩下g_tk=1671758421&format=jsonp&jsonpCallback=jsonp1

g_tk和format是你傳送的datajaonpCallback是與後臺約定的回撥名稱jsonp1儲存的是返回的資料jsonp1({xxxxx})等

②.可以手寫一個jsonp呼叫也可以使用外掛JSONP這裡使用了外掛

github:https://github.com/webmodules/jsonp  //使用說明

引用:

import originJSONP from 'jsonp'

自定義一個封裝的jsonp

export default jsonp(url,data,option){
  //這裡是將url和data物件進行拼接成url連結
  url += (url.indexOf('?')?'?':'&') + param(data); //param 這個是一個拼接函式將data專門轉化成url形式
  return new Promise((resolve,reject)=>{
          originJSONP(url,option,(error,data)=>{
              if(!err){
                 resolve(data)
              }else{
                 reject(err)
              }
          })
       })
}

Promise()充當非同步操作和回撥函式的中介,起到代理的作用

param()data資料物件轉化成url格式

function param(data){
    let url = '';
     //遍歷拼接物件
    for(var k in data){
      //以&a=123=yu=789 這樣形式拼接
      let value = data[k] !== undefined ?data[k] : '';
      url += `&${k}=${encodeURIComponent(value)}`;        //es6語法
    }
    return url ? url.substring(1):'';
}

在建立的config.js下寫入jsonp請求通用公共引數

export const commonParams = {
    g_tk: 5381,
    inCharset: 'utf-8',
    outCharset: 'utf-8',
    notice: 0,
    format: 'jsonp',
}
export const options = {
    param: 'jsonpCallback'
}
export const ERR_OK = 0

recommend.js檔案下寫入獲取QQ音樂輪播圖資料

import jsonp from '../common/js/jsonp' //引入自定義封裝的jsonp函式
import { commonParams, options } from './config'
export function getRecommend() {
    //輪播圖請求地址
   const url = 'https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg'; 
    利用es6物件方法進行淺拷貝將陣列物件合併到第一個{}物件中
    const data = Object.assign({}, commonParams, {
        platform: 'h5',
        uin: 0,
        needNewCode: 1
    })
    //呼叫jsonp方法 進行url拼接
    return jsonp(url, data, options)
}
③.元件頁面得到資料

將其js檔案引入元件中

import {getRecommend} from 'api/recommend';
import {ERR_OK} from 'api/config'g'

獲取資料:

  _getRecommend(){
          //因為return new Promise中有.then表示如果非同步成功完成就執行
        getRecommend().then(res=>{
          if(res.code === ERR_OK){
             console.log(res.data.slider)
             this.recommend = res.data.slider;        //放入元件data中接著傳入到輪埠元件中使用v-for渲染
          }
        })
      }
輪播圖元件用的vue-awesome-swiper

直接程式碼了使用規定的DOM結構:

<div class="slider" ref="slider">
  
    <swiper :options='swiperOption' ref="mySwiper">
      <!-- slides -->
      <swiper-slide v-for="(item,index) in recommend" :key="index">
        <a :href="item.linkUrl">
          <img class="swiper-img" :src="item.picUrl"  alt="">
        </a>
      </swiper-slide>
      <!-- Optional controls -->
      <div class="swiper-pagination" slot="pagination"></div>
    </swiper>
  </div>
import { addClass } from "common/js/dom.js";
export default {
  props: {
    recommend: {
      type: [Object, Array]
    }
  },
  data() {
    return {
      swiperOption: {
        pagination: {
          el: ".swiper-pagination",
          type: "bullets",
          clickable: true
        },
        loop: true, //意思是增加迴圈
        speed: 300,
        autoplay: {
          delay: 5000, //自動切換的時間間隔,單位ms
          stopOnLastSlide: false, //當切換到最後一個slide時停止自動切換
          stopOnLastSlide: true, //如果設定為true,當切換到最後一個slide時停止自動切換。
          disableOnInteraction: false, //使用者操作swiper之後,是否禁止autoplay。
          waitForTransition: true //等待過渡完畢。自動切換會在slide過渡完畢後才開始計時。
        }
      }
    };
  }
};
@import '../../common/stylus/variable.styl';

.slider >>> .swiper-pagination-bullet-active { // 表示只要div-swiper中子元件出現此class就進行樣式增加 <<<具有穿透意義
  transition-duration: 0.3s;
  width: 1.1rem;
  border-radius: 0.6rem;
  background: #fff !important;
  opacity: 1 !important;
}

.slider >>>.swiper-pagination-bullet {
  background-color: #fff;
  opacity: 0.5;
  margin: 0 0.4rem;
}

.swiper-img {
  width: 100%;
  height: 9.6rem;
}

效果圖