Vue音乐播放器(1)

1.vue.config.js

可以参考:
https://juejin.im/post/5bd02f98e51d457a944b634f
https://segmentfault.com/q/1010000016379336
https://www.jianshu.com/p/b001492fc9b9
https://www.jianshu.com/p/0824f625dfbb

更详细的可以参考官网:
https://cli.vuejs.org/zh/config/#vue-config-js
https://cli.vuejs.org/zh/guide/webpack.html

vue.config.js
1.publicPath(部署应用包时的基本URL)
2.outputDir(当运行vue-cli-service build时生成的生产环境构建文件的目录)
3.assetsDir(放置生成的静态资源(JS、CSS、img、fonts)的目录(相对于outputDir的目录))
4.pages(在 multi-page 模式下构建应用。每个“page”应该有一个对应的 JavaScript 入口文件。)
5.lintOnSave(是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码。)
6.configureWebpack(调整 webpack 配置最简单的方式就是在 vue.config.js 中的 configureWebpack 选项提供一个对象)
7.chainWebpack(Vue CLI 内部的 webpack 配置是通过 webpack-chain 维护的。)
8.css.moudles
9.css.extract
10.css.sourceMap
11.css.loaderOptions
12.devServer
13.devServer.proxy
14.pwa
15.pluginOptions
16.ESLint
17.TypeScript

关于configureWebpack和chainWebpack设置更多可以参考:https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F

看一个示例:

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
        .loader('vue-loader')
        .tap(options => {
          // 修改它的选项...
          return options
        })
  }
}

2.viewport

viewport要解决的问题是网页端内容在移动端显示的问题,移动端适配的目的是在不同尺寸的设备上,页面达到合理的展示(自适应)或者说是能够保持统一效果。

移动端有三个不同的视口概念:布局视口、视觉视口、理想视口

1.布局视口:在浏览器窗口css的布局区域,布局视口的宽度限制css布局的宽。为了能在移动设备上正常显示那些为pc端浏览器设计的网站,移动设备上的浏览器都会把自己默认的viewport设为980px或其他值,一般都比移动端浏览器可视区域大很多,所以就会出现浏览器出现横向滚动条的情况

2.视觉视口:用户通过屏幕看到的页面区域,通过缩放查看显示内容的区域,在移动端缩放不会改变布局视口的宽度,当缩小的时候,屏幕覆盖的css像素变多,视觉视口变大,当放大的时候,屏幕覆盖的css像素变少,视觉视口变小。

3.理想视口:一般来讲,这个视口其实不是真是存在的,它对设备来说是一个最理想布局视口尺寸,在用户不进行手动缩放的情况下,可以将页面理想地展示。那么所谓的理想宽度就是浏览器(屏幕)的宽度了。

为了理解起来更清楚一点,在网上找了两张比较易懂的图片。如果对这三个视口的概念还不是很清楚,看看下面几张图可能就会一目了然:

布局视口

在这里插入图片描述

视觉视口

在这里插入图片描述

2.那么如何设置理想视口呢?很简单,只需要在html的header中加入一段很重要的代码

 <meta name="viewport"content="width=device-width,user-scalable=no,initial-scale=1.0,  maximum-scale=1.0,minimum-scale=1.0">	

复制代码这行代码大家应该都不陌生,或者说是知道加了这行代码,然后页面的宽度就会跟我的设备宽度一致。实际上,它就是设置了理想视口,将布局视口的宽度设置成了理想视口(浏览器/设备屏幕的宽度)。

参考链接:https://juejin.im/post/5bfa99e0e51d4555557d26c6

移动端常用的头部配置

<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">

initial-scale [0.0-10.0] 定义初始缩放值
minimum-scale [0.0-10.0] 定义缩小最小比例,它必须小于或等于maximum-scale设置
maximum-scale [0.0-10.0] 定义放大最大比例,它必须大于或等于minimum-scale设置
user-scalable yes/no 定义是否允许用户手动缩放页面,默认值yes

3.index.html、main.js、app.vue

index.html 是你页面的模板, 首先会渲染这个 html 模板,然后 main.js 作为你入口的 JS,会自动被嵌入到 index.html 里的,这步是 webpack 帮你做的,然后就会加载这个 main.js,然后执行这个 main.js,在 main.js 里,我们通过 Vue 来渲染这个 app.vue,从而渲染整个页面。

4.我们在App.vue中引入stylus文件为什么有~

~是 stylus-loader 到东东,参考 https://github.com/shama/stylus-loader

~common 表示相对 common,然后我们在 webpack 配置了 common 的 alias,就能找到了它的路径了。

5.Vue中使用stylus报expected “indent”,got “eos”的错误

打开Preferences — settings – 右边添加上 “draw_white_space”:“all” 文本中就会出现 横线或者小点,如下图:

在这里插入图片描述

你会发现文件中出现横线或者小点是混乱,其实就是表明你的tab和空格是混乱的,导致缩进不一致,哪怕你肉眼看到是一致的,但是就是不一致。选中文本右下角 Spaces 或 Tab Size 点击一下选择 convert indentation to Spaces 或者 convert indentation to Tabs ,混合的横线和点会全部变成点或者是横线。这样就大功告成了。

在这里插入图片描述

参考链接:https://blog.csdn.net/qq_34919987/article/details/80565555

6.router-link组件激活的路由会在router-link组件上添加class "router-link-active"

所以我们可以对点击的时候设置样式:

&.router-link-active
        .tab-link
          color: $color-theme
          border-bottom: 2px solid $color-theme

同时,在stylus中,&.会匹配到同时有这个class的元素,&:匹配为元素 &表示父级class名

7.引入局部组件时候为什么import的组件第一个字母要大写?

因为他本质上是一个class,class的书写规范是第一个字母要大写。

8.JSONP原理及Promise封装

jsonp为什么能跨域?

1、 jsonp发送的并不是ajax请求;
2、 利用动态创建一个script标签,因为script标签是没有同源策略限制的,是可以跨域的;
3、 把这个script标签的src指向我们请求的服务端地址,这个地址会携带一个参数:callback ,一个回调函数,服务端会把数据通过这个回调函数返回给客户端,但是客户端没有这个函数怎么接收呢?所以在发送请求之前,要在全局(window)注册这样一个方法,利用这个方法,来获得数据;
4、 这个回调函数名需要跟服务端约定好,是一致的。

实现流程:

1.设定一个script标签

<script src="http://jsonp.js?callback=xxx"></script>

2.callback定义了一个函数名,而远程服务端通过调用指定的函数并传入参数来实现传递参数,将fn(response)传递回客户端

$callback = !empty($_GET['callback']) ? $_GET['callback'] : 'callback';
echo $callback.'(.json_encode($data).)';

3.客户端接收到返回的js脚本,开始解析和执行fn(response)

一句话阐述JSONP原理:动态生成一个JavaScript标签,其src由接口url、请求参数、callback函数名拼接而成,利用JS标签没有跨域限制的特性实现跨域请求。

有几点需要注意:
1.callback函数需要绑定在window对象上
2.服务端返回数据有特定格式要求:callback函数名+’(‘JSON.stringify(返回数据)+’)’
3.不支持post,因为JS标签本身就是一个get请求

具体代码如下,最后一段是调用函数的示例,这个函数返回一个promise对象,获取到数据时状态为resolve

 const jsonp = function (url, data) {
      return new Promise((resolve, reject) => {
        // 初始化url
        let dataString = url.indexOf('?') === -1 ? '?' : '&'
        let callbackName = `jsonpCB_${Date.now()}`
        url += `${dataString}callback=${callbackName}`
        if (data) {
         // 有请求参数,依次添加到url
          for (let k in data) {
            url += `&${k}=${data[k]}`
          }
        }
        let jsNode = document.createElement('script')
        jsNode.src = url
        // 触发callback,触发后删除js标签和绑定在window上的callback
        window[callbackName] = result => {
          delete window[callbackName]
          document.body.removeChild(jsNode)
          if (result) {
            resolve(result)
          } else {
            reject('没有返回数据')
          }
        }
        // js加载异常的情况
        jsNode.addEventListener('error', () => {
          delete window[callbackName]
          document.body.removeChild(jsNode)
          reject('JavaScript资源加载失败')
        }, false)
        // 添加js节点到document上时,开始请求
        document.body.appendChild(jsNode)
      })
    }
    jsonp('http://192.168.0.103:8081/jsonp', {a: 1, b: 'heiheihei'})
      .then(result => { console.log(result) })
      .catch(err => { console.error(err) })

参考文章:
https://www.jianshu.com/p/43b48648c730
https://segmentfault.com/a/1190000012096966
https://www.jianshu.com/p/f4642638c034
https://juejin.im/post/5b0d255e518825157914fbcd

还可以参考文章:
https://segmentfault.com/a/1190000007665361
https://zhangguixu.github.io/2016/12/02/jsonp/
http://ghmagical.com/article/page/id/AASiankfBJWp

9.Ajax介绍

先看一个简单的AJAX实例代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
function loadXMLDoc()
{
	var xmlhttp;
	if (window.XMLHttpRequest)
	{
		//  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
		xmlhttp=new XMLHttpRequest();
	}
	else
	{
		// IE6, IE5 浏览器执行代码
		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	}
	xmlhttp.onreadystatechange=function()
	{
		if (xmlhttp.readyState==4 && xmlhttp.status==200)
		{
			document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
		}
	}
	xmlhttp.open("GET","/try/ajax/ajax_info.txt",true);
	xmlhttp.send();
}
</script>
</head>
<body>

<div id="myDiv"><h2>使用 AJAX 修改该文本内容</h2></div>
<button type="button" onclick="loadXMLDoc()">修改内容</button>

</body>
</html>

其中最核心的依赖是浏览器提供的XMLHttpRequest对象,使得浏览器可以发出HTTP请求与接收HTTP响应。浏览器接着做其他事情,等收到XHR返回来的数据再渲染页面。

XMLHttpRequest使用主要分为下面几步:

//创建一个AJAX对象
let xhr=new XMLHttpRequest();
//不兼容 IE6以及以下(使用ActiveXObject)

//打开一个URL地址
//xhr.open("method","url",async,user.name,user.password)

xhr.onreadystatechange=()=>{
    if(xhr.readyState==4&&xhr.status==200){
        let res=xhr.responseText;//获取响应主体的内容
    }
};

//发送请求 (请求主体的内容的数据)
xhr.send()

readyState是XMLHttpRequest对象的一个属性,用来标识当前XMLHttpRequest对象处于什么状态。readyState总共有5个状态值,分别为0~4,每个值代表了不同的含义

0:未初始化 – 尚未调用.open()方法;
1:启动 – 已经调用.open()方法,但尚未调用.send()方法;
2:发送 – 已经调用.send()方法,但尚未接收到响应;
3:接收 – 已经接收到部分响应数据;
4:完成 – 已经接收到全部响应数据,而且已经可以在客户端使用了;

参考文章:
https://juejin.im/post/5b1cebece51d4506ae71addf
https://www.runoob.com/ajax/ajax-examples.html

10.vue-awesome-swiper 3.x使用

注意组件中下面代码的引入:

import 'swiper/dist/css/swiper.css'
import {swiper,swiperSlide} from "vue-awesome-swiper"

参考文章:https://www.jianshu.com/p/4f92c4461e3d

11.透传

透传的意思是我们代理接口接收到的参数,不做任何处理的再传到目标的第三方接口。
axios 发送请求返回 Promise 是 axios 库的一个设计。

Axios主要是对XMLHTTPRequest做了一层封装。

12.vue.config.js中使用proxyTable跨域原理

本质上就是通过node做一层接口转发。

13.该项目中为什么使用Express搭个服务再请求就可以跨域了?

流程是getDiscList中拼接url,再通过axios.get请求,返回的数据,就可以前端使用,vue.config.js中为什么设置成下面就可以跨域?

//recommend.js
//歌单数据
export function getDiscList () {
  // 线上环境地址,同学们根据自己的需要配置修改
  //如果debug不是null,url就等于'/api/getDiscList'. 如果debug不存在,url就等于’http....‘
  //const url = 'https://y.gtimg.cn/music/portal/js/v4/playlist_c258b4f.js'
  const url = debug ? '/api/getDiscList' : 'http://ustbhuangyi.com/music/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)
  })
}

//vue.config.js
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)
        }).catch((e) => {
          console.log(e)
        })
})

因为有些 header 在浏览器端是不能直接设置的,比如 referer。而 QQ 音乐一些的接口服务端(猜测)会验证 referer 或者是 host 这些 header。所以我们相当于通过一种代理的方式,先把请求发送给我们自己的 server(express 的 node 服务),然后我们的 server 在把这条请求转发到 QQ 音乐的服务端,而我们的 server 去请求 QQ 音乐的 server 也是通过 http 请求,和浏览器不同的是这个时候我们是可以设置任意 header 的。

14.vue-lazyload懒加载插件

1.安装插件
npm install vue-lazyload   --save

2.引用文件,一般在main.js全局引用
import Vue from 'vue'
import App from './App.vue'
import VueLazyload from 'vue-lazyload'

3.vue文件中将需要懒加载的图片绑定 v-bind:src 修改为 v-lazy 
<ul>
  <li v-for="img in list">
    <img v-lazy="img.src" >
  </li>
</ul>

参考文章:https://www.cnblogs.com/zzxuan/p/9690496.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值