其他

此应用的全部数据来自 QQ音乐,利用 axios 结合 node.js 代理后端请求抓取

全局通用的应用级状态使用 vuex 集中管理

全局引入 fastclick 库,消除 click 移动浏览器 300ms 延迟

页面是响应式的,适配常见的移动端屏幕,采用 flex 布局

疑难总结 & 小技巧

关于 Vue 知识 & 使用技巧

v-html 可以转义字符,处理特定接口很有用

watch 对象可以观测 属性 的变化

像这种父组件传达子组件的参数通常都是在data()里面定义的,为什么这里要放到created()定义,两者有什么区别呢?

因为这个变量不需要观测它的变化,因此不用定义在 data 里,这样也会对性能有所优化

不明白什么时候要把变量放在data()里,什么时候又不需要放 ?

需要监测这个数据变化的时候,放在 data() 里,会给数据添加 getter 和 setter

生命周期 钩子函数

生命周期钩子函数,比如 mounted 是先触发子组件的 mounted,再会触发父组件的 mounted,但是对于 created 钩子,又会先触发父组件,再触发子组件。

销毁计数器

如果组件有计数器,在组件销毁时期要记得清理,好习惯

对于 Vue 组件,this.$refs.xxx 拿到的是 Vue 实例,所以需要再通过 $el 拿到真实的 dom

关于 JS 知识 & 技巧

setTimeout(fn, 20)

一般来说 JS 线程执行完毕后一个 Tick 的时间约17ms内 DOM 就可以渲染完毕所以课程中 setTimeout(fn, 20) 是非常稳妥的写法

关于 webpack 知识 & 技巧

" ~ " 使 SCSS 可以使用 webpack 的相对路径

@import "~common/scss/mixin";

@import"~common/scss/variable";

babel-runtime 会在编译阶段把 es6 语法编译的代码打包到业务代码中,所以要放在dependencies里。

Fast Click 是一个简单、易用的库,专为消除移动端浏览器从物理触摸到触发点击事件之间的300ms延时

为什么会存在延迟呢?

从触摸按钮到触发点击事件,移动端浏览器会等待接近300ms,原因是浏览器会等待以确定你是否执行双击事件

何时不需要使用

FastClick 不会伴随监听任何桌面浏览器

Android 系统中,在头部 meta 中设置 width=device-width 的Chrome32+ 浏览器不存在300ms 延时,所以,也不需要

同样的情况也适用于 Android设备(任何版本),在viewport 中设置 user-scalable=no,但这样就禁止缩放网页了

IE11+ 浏览器中,你可以使用 touch-action: manipulation; 禁止通过双击来放大一些元素(比如:链接和按钮)。IE10可以使用 -ms-touch-action: manipulation

请求接口

jsonp:

XHR:

手写轮播图

利用 BScroll

BScroll 设置 loop 会自动 clone 两个轮播插在前后位置

如果轮播循环播放,是前后各加一个轮播图保证无缝切换,所以需要再加两个宽度

if (this.loop) {

width+= 2 *sliderWidth

}

初始化 dots 要在 BScroll 克隆插入两个轮播图之前

dots active状态 是通过判断 currentIndex 与 index 是否相等

currentIndex 更新是通过获取 scroll 当前 page,BScroll 提供了 api 方便调用

this.currentPageIndex = this.scroll.getCurrentPage().pageX

为了保证改变窗口大小依然正常轮播,监听窗口 resize 事件,重新渲染轮播图

window.addEventListener('resize', () =>{if (!this.scroll || !this.scroll.enabled) returnclearTimeout(this.resizeTimer)this.resizeTimer = setTimeout(() =>{if (this.scroll.isInTransition) {this._onScrollEnd()

}else{if (this.autoPlay) {this._play()

}

}this.refresh()

},60)

})

在切换 tab 相当于 切换了 keep-alive 的组件轮播会出问题,需要手动帮助执行,利用了 activated , deactivated 钩子函数

activated() {this.scroll.enable()

let pageIndex= this.scroll.getCurrentPage().pageXthis.scroll.goToPage(pageIndex, 0, 0)this.currentPageIndex =pageIndexif (this.autoPlay) {this._play()

}

},

deactivated() {this.scroll.disable()

clearTimeout(this.timer)

}

实测,首次打开网页并不会执行 activated,只有在之后切换 tab ,切回来才会执行

在组件销毁之前 beforeDestroy 销毁定时器是好习惯,keep-alive 因为是将组件缓存了,所以不会触发

beforeDestroy() {this.scroll.disable()

clearTimeout(this.timer)

}

后端接口代理

简单设置一下 Referer, Host,让别人直接通过浏览器抓到你的接口但是这种方式防不了后端代理的方式

前端 XHR 会有跨域限制,后端发送 http 请求则没有限制,因此可以伪造请求

axios 可以在浏览器端发送 XMLHttpRequest 请求,在服务器端发送 http 请求

(在项目编写阶段,可以将后端代理请求写在 webpack 的 dev 文件的 before 函数内)

before(app) {

app.get('/api/getDiscList', function(req, res) {

const url= 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg'axios.get(url, {

headers: {

referer:'https://c.y.qq.com/',

host:'c.y.qq.com'},

params: req.query

}).then((response)=>{

res.json(response.data)//axios 返回的数据在 response.data,要把数据透传到我们自定义的接口里面 res.json(response.data)

}).catch((e) =>{

console.log(e)

})

});

}

定义一个路由,get 到一个 /api/getDiscList 接口,通过 axios 伪造 headers,发送给QQ音乐服务器一个 http 请求,还有 param 参数。得到服务端正确的响应,通过 res.json(response.data) 返回到浏览器端

另外 因为是 http 请求数据,是ajax,所以 format 参数要将原本接口的 jsonp 改为 json

大公司怎么防止被恶意代理呢?当你的访问量大的时候,出口ip会被查到获取封禁,还有一种就是参数验签,也就是请求人家的数据必须带一个签名参数,然后这个签名参数是很难拿到的这个正确的签名,从而达到保护数据的目的

当然,获取的数据并不能直接拿来用,需要做进一步的规格化,达到我们使用的要求,所以在这方面单独封装了一个 class 来处理这方面的数据,具体请看src/common/js/song.js

flex 布局,热门歌单推荐

左侧 icon 固定大小,flex: 0 0 60px

flex 属性是 flex-grow , flex-shrink 和 flex-basis 的简写,默认值为 0 1 auto。后两个属性可选。

flex-grow 属性定义项目的放大比例,默认为 0,即如果存在剩余空间,也不放大。

flex-shrink 属性定义了项目的缩小比例,默认为 1,即如果空间不足,该项目将缩小。

flex-basis 属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

右侧 text 区块 自适应占据剩下的空间,并且内部也采用 flex,使用 flex-direction: column; justify-content: center; 来达到纵向居中排列

recommend 页面 利用 BScroll 滚动

Scroll 初始化但却没有滚动,是因为初始化时机不对,必须保证数据到来,DOM 成功渲染之后 再去进行初始化可以使用父组件 给 Scrol组件传 :data 数据,Scroll 组件自己 watch 这个 data,有变化就立刻 refesh 滚动

新版本 BScroll 已经自己实现检测 DOM 变化,自动刷新,大部分场景下无需传 data 了

所以也就 无需监听 img 的 onload 事件 然后执行 滚动刷新 了

loadImage() {if (!this.checkloaded) {this.checkloaded = true

this.$refs.scroll.refresh()

}

}

歌手页面 数据重构

歌手页面的结构是 热门、 A-Z 的顺序排列,但抓取的接口数据只是 100条常见的歌手,并且是乱序的,但我们可以利用接口的 Findex 进行数据的重构

首先可以定义一个 map 结构

let map ={

hot: {

title: HOT_NAME,

item: []

}

}

接着遍历得到的数据,将前10条添加到热门 hot 里然后查看每条的 Findex ,如果 map[Findex] 没有,创建 map[Findex] push 进新条目,如果 map[Findex] 有,则向其 push 进新条目

list.forEach((item, index) =>{if (index

map.hot.item.push(newSingerFormat({

id: item.Fsinger_mid,

name: item.Fsinger_name,

}))

}

const key=item.Findexif (!map[key]) {

map[key]={

title: key,

items: []

}

}

map[key].items.push(newSingerFormat({

id: item.Fsinger_mid,

name: item.Fsinger_name

}))

})

这样就得到了一个 符合我们基本预期的 map 结构,但是因为 map 是一个对象,数据是乱序的,Chrome 控制台在展示的时候会对 key 做排序,但实际上我们代码并没有做。

所以还要将其进行排序,这里会用到 数组的 sort 方法,所以我们要先把 map对象 转为 数组

let hot =[]

let ret=[]

let un=[]for (let key inmap) {

let val=map[key]if (val.title.match(/[a-zA-z]/)) {

ret.push(val)

}else if (val.title ===HOT_NAME) {

hot.push(val)

}else{

un.push(val)

}

}

ret.sort((a, b)=>{return a.title.charCodeAt(0) - b.title.charCodeAt(0)

})return hot.concat(ret, un)

根据 title 字母的 Unicode 编码大小排序的(比如:'A'.charCodeAt(0)=65;'B'.charCodeAt(0)=66)然后就a,b,c,d...的顺序了

歌手页面

shortcut 定位

因为 shortcut 整体的高度是不确定的,所以采用的是 top:50% 之后,transform: translateY(-50%); 这样就能动态的根据内容高度而垂直居中

歌手页面 区块与锚点 的联动

点击或滑动 shortcut 不同的锚点 ,自动滚动至相应的标题列表

利用了 BScroll 的 api ,scrollToElement

scrollToElement 可以滚动至相应的 index 值的区块

第一次点击触碰 shortcut ,获取点击具体锚点的 index 值,记录触碰位置的 index ,利用 scrollToElement ,滚动至相应 index 的区块而之后,滑动锚点实现滚动是利用 touchmove 事件,将两次触碰的的位置计算值变成 delta 差值:变成改变后的锚点区块 index 值,再将首次触碰的 index 值 + 改变的 delta 值,再利用 scrollToElement ,滚动至相应的区块

onShortcutTouchStart(e) {

let anchorIndex= getData(e.target, 'index') //获取 点击具体锚点的 index 值

let firstTouch = e.touches[0] //第一次触碰的位置

this.touch.y1 = firstTouch.pageY //保存 第一次触碰的位置的Y值

this.touch.anchorIndex = anchorIndex //保存 第一次触碰时的锚点 index 值

this._scrollTo(anchorIndex)

},

onShortcutTouchMove(e) {

let firstTouch= e.touches[0]this.touch.y2 =firstTouch.pageY

let delta= (this.touch.y2 - this.touch.y1) / ANCHOR_HEIGHT | 0 //两次触碰 Y 轴的偏移锚点值

let anchorIndex = +this.touch.anchorIndex + delta //获取 偏移了多少 index 值 ,因为 anchorIndex 是字符串,所以要转成数字再相加

this._scrollTo(anchorIndex)

},

_scrollTo(index) {this.$refs.listview.scrollToElement(this.$refs.listGroup[index], 200)

}

{{group.title}}

{{item.name}}

{{item}}

music功能 vue_Vue 实现的音乐项目 music app 知识点总结分享相关推荐

  1. Vue 实现的音乐项目 music app 知识点总结分享

    其他 此应用的全部数据来自 QQ音乐,利用 axios 结合 node.js 代理后端请求抓取 全局通用的应用级状态使用 vuex 集中管理 全局引入 fastclick 库,消除 click 移动浏 ...

  2. 第一份功能较多的安卓项目--纪念日app

    因为正值跟女朋友在一起的半周年.所以想着做个她需要的app给她用.其实网上同样功能的app很多,但都有广告,而且比较庞大,她的手机又比较老卡,所以就根据她的需求来写,哈哈,算是我的第一个项目经理吧. ...

  3. Vue2 - 网易云音乐项目笔记(基于Vant UI组件库)

    目录 一.项目技术 二.准备工作 1.初始化Vue项目 2.配置Vant UI组件库 3.下载并使用vue-router库 4.接口API 5.postcss插件 三.分析页面实现功能 1.路由页面准 ...

  4. 微信小程序云音乐项目

    微信小程序云音乐项目 微信小程序云音乐项目 1. 项目介绍 技术栈 项目使用库 项目目标 2. 页面效果和功能展示 3. 项目源码与 API 接口 4. 项目说明 5. 致谢 微信小程序云音乐项目 1 ...

  5. 视频编辑器-MovieMator简洁使用-功能和快速入门-创建项目、导入和导出

    视频编辑器-MovieMator 简洁使用-创建项目.导入和导出          MovieMator是一个简单但功能强大的免费视频编辑软件.它不仅允许用户进行基本的编辑工作,如修剪.裁剪.分割.旋 ...

  6. 云课堂云音乐项目总结

    一.云课堂 项目要求: 1.完成PC端首页.课程详情页.个人中心页.课程搜索页的静态布局 2.数据请求并渲染到页面 3.首页要实现的功能: 用户登录.注册.忘记密码.退出登录 注册.忘记密码正则校验 ...

  7. 原生微信小程序云音乐项目总结

    功能概述:实现了基本云音乐APP的功能. 三个tabBar页面: 首页:视频页: 个人中心: 其他功能页面 登录页: 每日推荐页: 播放歌曲:  一.首页 简单运用了swiper和scroll-vie ...

  8. 【阿里云课程】1小时快速掌握Tensorflow核心功能,完成完整的项目实践

    大家好,继续更新有三AI与阿里天池联合推出的深度学习系列课程,本次更新内容为第7课中一节,介绍如下: Tensorflow快速入门与实践 本节课内容为:深度学习系列课程第7期,Tensorflow快速 ...

  9. 【阿里云课程】1小时快速掌握Caffe核心功能,完成完整的项目实践

    大家好,继续更新有三AI与阿里天池联合推出的深度学习系列课程,本次更新内容为第7课中一节,介绍如下: Caffe快速入门与实践 本节课内容为:深度学习系列课程第7期,Caffe快速入门与实践,讲述Ca ...

最新文章

  1. Python网络爬虫与信息提取(二)(BeautifulSoup库)
  2. 大型网站架构的发展演变过程
  3. 芒果TV崩了?项目组在家办公效率不行呀!
  4. @select 怎么写存储过程_MySQL4:存储过程和函数
  5. python能print中文吗_python怎么print汉字
  6. python for循环连续输入五个成绩判断等级_Python基础(1)——输入输出/循环/条件判断/基本数据类型...
  7. 数据库选项--自动更新统计
  8. 拯救万千学子于水深火热之中!Facebook开源无梯度优化工具
  9. html input 字体颜色_HTML常用标签汇总
  10. git向码云上提交项目
  11. BigQuant*中金财富“启明星”创新量化交易大赛开启,月月都拿奖
  12. 东沃电子:瞬态电压抑制二极管选型指南
  13. python 生孩子朋友圈_新生儿出生朋友圈说说,生孩子报喜唯美句子
  14. #Javascript基础
  15. Ubuntu22.04.01Desktop桌面版安装记录221109
  16. 本地项目及依赖上传私服nexus
  17. 现代大学英语精读第二版(第四册)学习笔记(原文及全文翻译)——16B - Is Everybody Happy?(人人都幸福吗?)
  18. 免费域名和付费域名的几个区别
  19. 微信昵称中表情保存到数据库问题
  20. javascript 框架_Javascript框架的成本

热门文章

  1. 梦起北邮 Cocos伴数媒学子共成长
  2. 【时间预测+速度规划+ADRC】移动机器人高精度轨迹跟踪控制
  3. 如何配置php环境变量
  4. 2023 API酷狗音乐MV直链解析接口源码
  5. java输入矩阵规格和行数,输出矩阵
  6. python表情包爬虫程序_Python网络爬虫7 - 爬取表情包
  7. svn服务器配置文件添加用户后需要重启吗,linux 中 svn 服务器搭建 重启
  8. 35岁程序员找不到工作
  9. SQL笔记4:mysql切割字符串的4种方式
  10. Linux中打包+压缩命令(超详细)