博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vuejs2.0 高级实战 全网稀缺 独立开发专属音乐WebAPP 更新中。。。
阅读量:7154 次
发布时间:2019-06-29

本文共 10064 字,大约阅读时间需要 33 分钟。

这里写图片描述

词条

目前市面上还没有一个Vue 2.0 的高级教学,都是一些基础的入门课程,你很难找到一个基于Vue.js的复杂应用的教学, 但是,我们为你准备了这门独一无二的Vue 2.0 高级实战课程


src简单的介绍

这里写图片描述

入口文件

import 'babel-polyfill'  //写在第一位import Vue from 'vue'import App from './App'import router from './router'import fastclick from 'fastclick'import VueLazyload from 'vue-lazyload'import store from './store'import 'common/stylus/index.styl'/* eslint-disable no-unused-vars */// import vConsole from 'vconsole'fastclick.attach(document.body)Vue.use(VueLazyload, {  loading: require('common/image/default.png')  //传一个默认参数})/* eslint-disable no-new */new Vue({  el: '#app',  router,  store,  render: h => h(App)})
babel-polyfill是es6底层铺垫即支持一些API,比如promise

Tab页面

`router-link默认是a标签,我们通过tag指定为div
.router-link-active这个class是组件自带的`

APP.vue

仔细的看一下引入的组件Tab以及一个布局方式

jsonp的封装

import originJsonp from 'jsonp'   //jsonp 结合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)      }    })  })}export function param(data) {  let url = ''  for (var k in data) {    let value = data[k] !== undefined ? data[k] : ''    url += '&' + k + '=' + encodeURIComponent(value)    //视频代码     //url += `&${k}=${encodeURIComponent(value)}`   es6语法  }  return url ? url.substring(1) : ''}
重点关注一下URL的拼接可以用到项目中

API/recommend.js 使用jsonp 调取轮播图的数据

import jsonp from 'common/js/jsonp'import {commonParams, options} from './config'export function getRecommend() {  const url = 'https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg'  const data = Object.assign({}, commonParams, {  //assign es6语法    platform: 'h5',    uin: 0,    needNewCode: 1  })  return jsonp(url, data, options)}
用到了es6对象的合并方法Object.assign

config.js

export const commonParams = {  g_tk: 1928093487,  inCharset: 'utf-8',  outCharset: 'utf-8',  notice: 0,  format: 'jsonp'}export const options = {  param: 'jsonpCallback'}export const ERR_OK = 0
定义一些公共参数,不用每次再去重写

components/recommend.vue 在组件中调用接口

`这里用到了slider组件以及slot的知识,也遇到了一个坑,因为数据响应
必须确定有数据v-if="recommends.length"才能保证插槽的正确显示`
export default {    data() {      return {        recommends: []      }    },    created() {      this._getRecommend()    },    methods: {            _getRecommend() {        getRecommend().then((res) => {          if (res.code === ERR_OK) {            this.recommends = res.data.slider          }        })      }    },    components: {      Slider    }  }

热门歌单推荐

在这里没有用jsonp而是用了axios,是因为接口有host、referer校验不得使用后端代理接口的方式去处理

bulid目录下dev-server.js处理代理

require('./check-versions')()var config = require('../config')if (!process.env.NODE_ENV) {  process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)}var opn = require('opn')var path = require('path')var express = require('express')var webpack = require('webpack')var proxyMiddleware = require('http-proxy-middleware')var webpackConfig = require('./webpack.dev.conf')var axios = require('axios') //第一步// default port where dev server listens for incoming trafficvar port = process.env.PORT || config.dev.port// automatically open browser, if not set will be falsevar autoOpenBrowser = !!config.dev.autoOpenBrowser// Define HTTP proxies to your custom API backend// https://github.com/chimurai/http-proxy-middlewarevar proxyTable = config.dev.proxyTablevar app = express()var apiRoutes = express.Router()   //以下是后端代理接口 第二步apiRoutes.get('/getDiscList', function (req, res) {  var 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)  //输出到浏览器的res  }).catch((e) => {    console.log(e)  })})apiRoutes.get('/lyric', function (req, res) {  //这是另一个接口下节将用到  var url = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg'  axios.get(url, {    headers: {      referer: 'https://c.y.qq.com/',      host: 'c.y.qq.com'    },    params: req.query  }).then((response) => {    var ret = response.data    if (typeof ret === 'string') {      var reg = /^\w+\(({[^()]+})\)$/      var matches = ret.match(reg)      if (matches) {        ret = JSON.parse(matches[1])      }    }    res.json(ret)  }).catch((e) => {    console.log(e)  })})app.use('/api', apiRoutes)   //最后一步var compiler = webpack(webpackConfig)var devMiddleware = require('webpack-dev-middleware')(compiler, {  publicPath: webpackConfig.output.publicPath,  quiet: true})var hotMiddleware = require('webpack-hot-middleware')(compiler, {  log: () => {}})// force page reload when html-webpack-plugin template changescompiler.plugin('compilation', function (compilation) {  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {    hotMiddleware.publish({ action: 'reload' })    cb()  })})// proxy api requestsObject.keys(proxyTable).forEach(function (context) {  var options = proxyTable[context]  if (typeof options === 'string') {    options = { target: options }  }  app.use(proxyMiddleware(options.filter || context, options))})// handle fallback for HTML5 history APIapp.use(require('connect-history-api-fallback')())// serve webpack bundle outputapp.use(devMiddleware)// enable hot-reload and state-preserving// compilation error displayapp.use(hotMiddleware)// serve pure static assetsvar staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)app.use(staticPath, express.static('./static'))var uri = 'http://localhost:' + portvar _resolvevar readyPromise = new Promise(resolve => {  _resolve = resolve})console.log('> Starting dev server...')devMiddleware.waitUntilValid(() => {  console.log('> Listening at ' + uri + '\n')  // when env is testing, don't need open it  if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {    opn(uri)  }  _resolve()})var server = app.listen(port)module.exports = {  ready: readyPromise,  close: () => {    server.close()  }}

API/recommend.js 使用jsonp 调取热门歌单的数据

export function getDiscList() {  const url = '/api/getDiscList'  const data = Object.assign({}, commonParams, {    platform: 'yqq',    hostUin: 0,    sin: 0,    ein: 29,    sortId: 5,    needNewCode: 0,    categoryId: 10000000,    rnd: Math.random(),    format: 'json'  })  return axios.get(url, {    params: data  }).then((res) => {    return Promise.resolve(res.data)  })}
接下来开发推荐页面滚动列表--因为很多页面都支持滚动,所以抽出来一个公用组件Scroll.vue

recommend.vue

可能会遇到一个问题,初始化后不能滚动,是因为高度的问题,所以给img加了一个方法,这里提到了vuex的使用,那怎么给vuex提交数据细心的同学可能会发现↓↓↓↓↓
接下来是歌手页面,由于考虑到二级路由要跳到歌手详情,所以抽出一个独立组件listview.vue,涉及到数据结构处理、类的创建、es6的字符拼接、数组map方法、自定义data属性获取方法的封装

singer.vue

引入listview组件,有一个20毫秒的定时器,关键在于左右联动的思路很重要,以及关于diff的处理增强用户体验
歌手详情页,为了组件重用抽出来一个music-list.vue,在此基础又抽出来一个song-list.vue,用到了v-html来转义字符、计算属性里返回对象的某几个key比如只传入name或者头像、mapGetters获取vuex的数据


下面是父组件歌手详情,封装了一个createSong的类,可在源码中查看提高了代码的重用性、扩展性因为是面向对象的方式
播放器内置组件 player.vue,通过actions的方法--selectPlay,在此组件拿到currentSong,这里再重点说一下mutations和它的type要做到命名一致,nutations本质就是函数,第一个参数是state第二个参数是要修改的对象值

player组件定义到了app.vue,因为它不属于某一个页面是全局的,mapgetters是一个数组,多次批量修改mutation就要用到actions

重点是动画的过度效果,结合钩子函数实现飞入飞出动画,用到了开源动画库,create-key-animation

音乐播放事件togglePlaying,因为播放的暂停开始要调用audio的方法,可能会出现拿不到元素报错,这是用到了nextTic延时函数,添加class可以用到计算属性,歌曲的前进后退通过currentIndex,有一个小问题,暂停后切换到下一首歌要自动播放,快速点击的时候结合 ready err方法避免快速点击页面报错

条形进度条,通过audio获取可以读写的当前播放时间,将其时间戳转为时分秒格式,通过_pad给秒位前补零,做到与设计图一致,定义基础组件progress-bar,事件拖动和点击滚动条的交互实现,也就是说拖动无非就是三个事件,start move end,拖动开始前加一个开关表示初始化完成,如果拖动前是暂停状态,拖动后再让其播放

圆形进度条,用到了SVG再通过两个circle实现,完全可以应用到实际工作中

播放模式,用到util里面的shuttle函数把数组打乱,用到es6的findindex函数,由于要实时改变currentSong,父组件监听事件会被触发所以做了一个判断,如果id相同什么都不错,因为这个时候还没触发事件

转载地址:http://qyogl.baihongyu.com/

你可能感兴趣的文章
Python与Cisco 的事儿
查看>>
RHEL6内核升级及 LVM管理
查看>>
Zabbix简介
查看>>
使用PIL改变图像格式及尺寸
查看>>
写在2014年前
查看>>
富士通:寻找重塑的力量
查看>>
我的友情链接
查看>>
python将日志导入数据库代码案例 3
查看>>
CodeIngiter 2.2.x 与 Smarty3 整合的方案 解决CI的不足
查看>>
Windows L2TP客户端设置
查看>>
How to Run Your Own Git Server
查看>>
Servlet之sendRedirect和getRequestDispatch
查看>>
zabbix服务器监控交换机添加图像Graphs
查看>>
Windows Server 2012显示桌面图标!
查看>>
bzoj 2005: [Noi2010]能量采集
查看>>
【Android测试】【第三节】ADB的无线模式
查看>>
PostFix邮件网关无法向公×××递邮件问题分析
查看>>
vim中delete(backspace)键不能向左删除
查看>>
vue_初次体验_1
查看>>
Powershell 之多线程监控网页状态
查看>>