项目预览地址:http://ustbhuangyi.com/music/#/recommend
获取歌曲 url 地址方法升级:https://github.com/ustbhuangyi/vue-music/issues/111
参考:
https://github.com/ustbhuangyi/vue-music/issues/164
https://github.com/ustbhuangyi/vue-music/issues/136
https://github.com/ustbhuangyi/vue-music/issues/111
https://github.com/ustbhuangyi/vue-music/issues/114
https://github.com/ustbhuangyi/vue-music/issues/77
1、可以把一些常用的、操作dom的方法封装到js里面,比如addClass
2、页面中的方法,尽量封装成一个个小方法,减少每个方法里面的代码
3、recommend.vue,为什么要在引入轮播图插件的外面进行判断?原因是:created(){} 里面获取数据是一个异步操作,请求后台数据需要一点时间
4、slider.vue,mounted里的setTimeout的时间为20的原因,浏览器刷新一次的时间为17毫秒
5、app.vue
当切换组件后,再切回来,数据会再请求一次
优化方法
在app.vue里面,添加
1 <keep-alive> 2 <router-view></router-view> 3 </keep-alive>
添加keep-alive后,数据会保存到内存中
6、slide.vue
1 destroyed () { 2 clearTimeout(this.timer) 3 }
当组件被切换出去,生命周期就进入到destroyed,要进行clearTimeout。
注意:当组件中用到了计时器时,要在destroyed中进行clearTimeout,释放内存资源,这是一种好的编程习惯
7、scroll.vue组件
通过监控data数据的变化来调用refresh()方法
8.、recommend.vue组件
在使用scroll组件的时候,传入data的为discList的原因是:
discList数据后获取,但有一个问题,如果recommend数据没有获取到,或者在discList数据之后获取,那么滚动的时候,就会少了下面这一块区域
解决的办法:
结果分析:上面这一块的高度,是由图片撑开的,所以我们可以给图片绑定一个load方法,当图片加载时,就调用
1 loadImage () { 2 if (!this.checkloaded) { 3 this.checkloaded = true 4 setTimeout(() => { 5 this.$refs.scroll.refresh() 6 }, 20) 7 } 8 }
小技巧:图片有很多,我们不需要每一张图片都调用load方法,可以添加有一个判断值 this.checkloaded
9、在页面中,我们要加载很多图片,不需要一次性全部加载,只要滑动到相应位置再加载,这时候就需要用到vue-lazyload
地址:https://github.com/hilongjw/vue-lazyload
使用方法,先用npm 安装vue-lazyload
main.js 引入vue-lazyload
需要用到的地方
<img>标签里面,把:src改成v-lazy
10、当一个组件中,同时使用了fastclick 和better-scroll,且better-scroll设置了click:true属性,这时会出现一个问题,
无法点击了,解决办法是,在Iimg处设置class="needsclick",这个是fastclick的属性
11、数据没有加载时显示的效果,请看 loading.vue
12、singer.vue
数组进行排序,用来sort方法,sort方法内部的返回俩个数的charCodeAt相减的bollean值
13、listview.vue
这个表示向下取整,原因:
因为|这个是或位操作符,意思是先将数值转换成32位二进制整数值(如果有小数则忽略),再对二进制上每一位进行或运算,得出结果;
这里xxx|0,因为0的二进制就是0000000...00一共32位(32个0),无论任何数对0进行或运算都是原来的数,因此可以用它来进行向下取整
14、scroll.vue (第5章用到)
15、
16、子路由的配置
router文件夹下的Index.js里面
singer.vue里面
// router的编程式调用接口,类似于申明式<router-link :to="...">
参考地址:http://blog.csdn.net/sinat_17775997/article/details/68941091
17、在vue中,用export注册的东西,其他页面获取的时候,要用 import {Xx} from ,或者import * as 自己起的名字 from
18、singer-datail.vue
刷新详情页的时候,因为没有singer.id,容易要加这个判断,返回到singer页面。(小技巧)
19、singer-detail.vue
这块定义musicData的时候,为什么要用{musicData}?
item:是这样的
一个object里面包含一个musicData的object,这个项目我们只需要musicData,所以可以这样定义:{musicData}
20、music-list.vue
这块为什么要用this.$refs.list.$el.style.top这种方法
因为this.$refs.list是Vuecomponent
使用了$el,才能返回dom,,才可以用来设置style
21、music-list.vue
如果this.$refs.layer是dom。要设置style,上面这俩种方式都可以
22、dom.js
在script里面设置style,我们需要兼容各种浏览器,为了不需要重复写代码,在dom.js里面封装了相应的方法
1 let vendor = (() => { 2 let transformNames = { 3 webkit: 'webkitTransform', 4 Moz: 'MozTransform', 5 O: 'OTransform', 6 ms: 'msTransform', 7 standard: 'transform' 8 } 9 for (let key in transformNames) { 10 if (elementStyle[transformNames[key]] !== undefined) { 11 return key 12 } 13 } 14 return false 15 })() 16 export function prefixStyle (style) { 17 if (vendor === false) { 18 return false 19 } 20 21 if (vendor === 'standard') { 22 return style 23 } 24 25 return vendor + style.charAt(0).toUpperCase() + style.substr(1) 26 }
如何使用
music-list.vue
1 const transform = prefixStyle('transform') 2 3 this.$refs.layer.style[transform]=`translate3d(0,${translateY}px,0)`
23、切记mapMutations是{},mapActions是[]
24、play.vue
解析里面的值:
// 获取初始位置和初始缩放比例 _getPosAndScale () { const targetWidth = 40 // mini左侧图标大小 const paddingLeft = 40 // mini左侧图标距离左侧的长度 const paddingBottom = 30 // mini左侧图标距离底部的长度 const paddingTop = 80 // nomal唱片距离头部的长度 const width = window.innerWidth * 0.8 // nomal唱片一半的宽度 const scale = targetWidth / width const x = -(window.innerWidth / 2 - paddingLeft) const y = window.innerHeight - paddingTop - width / 2 - paddingBottom return { x, y, scale } },
1是targetWidth 2是paddingBottom 3是paddingLeft 4是paddingTop 5是X 6是Y
25、play.vue
这部分讲的是如何用vue钩子实现css动画(以后可以看)
26、play.vue
快速点击上一首、下一首的时候,会出现上面的错误,这是因为audio标签里面有play(从加载到播放执行)和error(url错误或者由于昂罗问题没有url执行)俩个方法
解决办法是:
给audio绑定play和error方法,定义一个songReady变量,在ready和error里面,修改songReady的值
26、play.vue
1 let index = list.findIndex((item) => { 2 return item.id === this.currentSong.id 3 })
数组findIndex(条件)传入一个测试条件,符合就返回相应的Index
链接:http://www.runoob.com/jsref/jsref-findindex.html
27、common.js/song.js
1 getLyric () { 2 getLyric(this.mid).then((res) => { 3 if (res.retcode === ERR_OK) { 4 this.lyric = Base64.decode(res.lyric) 5 console.log(this.lyric) 6 } 7 }) 8 }
后台返回的res.lyric是base数据,所以我们用js-base64这个插件来解析
https://github.com/dankogai/js-base64
28、解析歌词的插件 lyric-parser
https://github.com/ustbhuangyi/lyric-parser
29、Vue.mixin 全局注册
当出现这个的 时候,列表的bottom值为60,为了实现这个,新建了一个mixin.js,然后在需要的vue里面调用
api:https://cn.vuejs.org/v2/api/#Vue-mixin
30、search-box.vue组件的debounce方法
当我们在输入框输入内容的时候,会自动调用search方法查询数据,这是有点不合理的,优化的方式是添加一个debounce方法
思路是:这个方法里面加了一个延迟执行,在延迟里面调用search方法,这样在快速输入的时候,就不会没输入一个值都查询后台数据了
31、cache.js
localstorage和sessionstorage保存的是字符串,如果想保存数组,可以使用插件storage
地址:https://github.com/ustbhuangyi/storage
32、state.js中,我们定义的state既可以使用默认的值,也可以调用方法,从之前保存的地方获取,比如localstorage
33、playlist.vue组件,外层绑定了click事件,内层点击也会触发,解决办法是在最靠近外层的那一层添加一行代码 :@click.stop
34、playlist.vue组件,列表改变时的动画,用transtion-group,比如之前的ul列表,可以改成<transition-group name="和transition一样" tag="ul(渲染)">,li要指定一个key值,用来区分不同的li
参考地址:http://blog.csdn.net/wngzhem/article/details/53841640
35、switches.vue组件,这是一个基础组件,基础组件不做任何逻辑操作,都是通过emit把值传给父主组件,父组件逻辑操作以后,把值传给基础组件
36、新接口: https://github.com/ustbhuangyi/vue-music/issues/136