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