首先做项目配置 安装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;
}
效果图