基于Vue2.x全家桶的Web音乐App学习总结

Vue-music项目概述

这是一个基于vue2.x全家桶和真实线上数据接口开发的一个媲美原生的移动端音乐App,已完成页面包括有歌单推荐页,歌手列表页,歌手详情页,播放器页面,排行榜页面和搜索页面。

要点总结

Vue

  • <router-link>:通过to属性指定目标地址;配置tag属性生成别的标签,当目标路由成功激活时,将自动在tag生成的标签上自动设置router-link-active类名

  • <router-view>:用于构建单页应用时,渲染指定路由对应的组件,可当作是要匹配组件的容器

  • <keep-alive>:在组件切换过程中将状态保留在内存中,防止重复渲染DOM

  • <slot>:Vue的内容分发机制,即可以将父组件的内容分发到子组件的指定位置中,<slot>则作为承载分发内容的出口

JS

  • Promise:异步编程的一种解决方案,在项目中的运用:
export default function jsonp(url, data, option) {
    url += (url.indexOf('?') < 0 '?' : '&') + param(data)
    return new Promise((resolve, reject) => {
        originJSONP(url, option, (err, data) => {
            if (!err) {
                resolve(data)
            } else {
                reject(err)
            }
        })
    })
}
  • Object.assign():用于对象的合并,将源对象的所有可枚举属性,复制到目标对象。第一个参数是目标对象,后面的参数都是源对象
const data = Object.assign({}, commonParams, {
    platform: 'h5',
    uin: 0,
    needNewCode: 1
})
  • setTimeout(fn, 20):JS线程执行完毕后一个Tick的时间约17ms内DOM就有可以渲染完毕,所以setTimeout(fn, 20)是非常稳妥的写法

CSS

  • Stylus:编写模块化的CSS
  • Flex:弹性布局,实现常见的移动设备的响应式布局

库的使用

  • better-scroll
    • 易错better-scroll只会处理容器的第一个子元素的滚动;且子元素的宽度(或高度)一定要大于容器的宽度(或高度)才可以滚动;当一个页面出现不同滚动需求时(例如歌单推荐页即有横向又有纵向的滚动),可进行嵌套使用,但必须用一个容器将两部分滚动包裹在一起
    • slider组件:需配置参数值snap:true,另外设置snapLoop:true表示无缝循环轮播,snapThreshold:0.3表示手指滑动大于这个阈值则滑动到下一页,snapSpeed:400表示轮播图切换的动画时间
    • 事件
      • scrollEnd表示滚动结束时触发
    • 函数
      • refresh():强制scroll重新计算,当better-scroll中的元素发生变化的时候调用此方法
      • getCurrentPage():获取滚动的当前页,返回对象结构为{x, y, pageX, pageY},x,y代表滚动横向和纵向的位置;pageX,pageY表示横向和纵向的页面索引。用法如:getCurrentPage().pageX
      • goToPage(x, y, time, easing):滚动到对应的页面,x表示横向页面索引,y表示纵向页面索引,time表示动画,easing表示缓动函数(可省略)
  • jsonp:获取轮播图数据时用到,传入的url需做字符串处理,data需进行encodeURIComponent()编码处理,再结合new Promise()异步获取数据

  • axios:基于promise的HTTP库,可以用在浏览器和node.js中,项目中用的最多的通过代理后端服务器获取数据的手段

// 歌单数据获取
before(app) {
    app.get('/api/getDiscList', function(req, res) {
        var url = "https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg"
        axios.get(url, {
            header: {
                referer: 'http://y.qq.com',
                host: 'c.y.qq.com'
            },
            params: req.query
        }).then((response) => {
            res.json(response.data)
        }).catch((e) => {
            console.log(e)
        })
    })
}

export function getDiscList() {
    const url = '/api/getDiscList'

    const data = Object.assign()

    return axios.get(url, {
        params: data
    }).then((res) => {
        return Promise.resolve(res.data)
    })
}
  • vue-lazyload:懒加载图片,优化用户体验

轮播图

  • 设置轮播宽度Bscroll设置snapLoop时会自动克隆两个轮播图插在前后位置,为了保证轮播图无缝切换,需要增加两个宽度;同时加入窗口变化时不再增加宽度的限制
if (this.loop && !isResize) {
    width += 2*sliderWidth
}
  • 初始化dots:dots的数量由轮播图数量决定,因此需在设置克隆插入轮播之前进行

  • 初始化滚动:通过getCurrentPage()获取当前滑动页的索引赋值给currentPageIndex,与dots的index比较是否相等,以此添加active

  • 自动播放:自定义定时器结合goToPage()跳转到相应的页面

_play() {
    let pageIndex = this.currentPageIndex + 1
    if (this.loop) {
        pageIndex += 1
    }
    this.timer = setTimeout( ()=> {
        this.slider.goToPage(pageIndex, 0, 400)
    }, this.interval)
}
  • 清除定时器:每次手指滑动时都应清除定时器,避免索引值的获取发生错乱;组件销毁时都应清除定时器达到释放内存的目的

  • 监听窗口变化:为了保证窗口变化时依旧能够正常轮播,应监听resize事件来重新渲染轮播图并计算宽度

window.addEventListener('resize', ()=> {
    if (!this.slider) {
        return
    }
    this._setSliderWidth(true)
    this.slider.refresh()
})

歌手列表数据聚合

// 定义Singer类(相当于ES5的构造函数)创建属性,处理avatar字段
export default class Singer {
   
   
    constructor({id, name}) {
        this.id = id
        this.name = name
        this.avatar = `https://y.gtimg.cn/music/photo_new/T001R300x300M000${id}.jpg?max_age=2592000`
    }
}

_normalizeSinger(list) {
    let map = {
        hot: {
            title:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值