一、关于Vuex
Vuex是一个专为Vue.js应用程序开发的状态管理模式。
1.vuex有哪几种属性
state, getters, mutations, actions, modules。
1)state:vuex的基本数据,用来存储变量,只能有一个(字符串,数组,对象)
2)getters:从基本数据(state)派生的数据,相当于state的计算属性
3)mutations:提交更新数据的方法,相当于我们vue里面的methods,也是定义方法的,只不
过这个方法可以在多个组件调用了。但必须是同步的(如果需要异步使用actions)
使用\(\color{red}{commit}\)调用
最后使用
4)actions:和mutations的功能大致相同,不同之处在于 ==》a. actions 提交的是
mutation,而不是直接变更状态。 b. actions 可以包含任意异步操作。
调用的话就不是使用commit了,而是使用\(\color{red}{dispatch}\)
5)modules:模块化vuex,可以让每一个模块拥有自己的state、mutations、actions、getter
s,使得结构非常清晰,方便管理。
2.Vuex优点(不使用Vuex的缺点)
-
可维护性下降(你要想修改数据,你得维护三个地方)
-
可读性会下降(因为一个组件里的数据,你根本就看不出来是从哪来的)
-
增加耦合,大量的上传派发,会让耦合性大大的增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。
-
兄弟组件通信用Vuex
二、iframe
1. iframe优缺点
优点:
1)iframe能够把嵌入的网页原样展现出来;
2)模块分离,便于更改,如果有多个网页引用iframe,只需要修改iframe的内容,就可以实现调用的每一个页面内容的更改,方便快捷;
3)网页如果为了统一风格,头部和版本都是一样的,就可以写成一个页面,用iframe来嵌套,增加代码的可重用;
4)如果遇到加载缓慢的第三方内容如图标和广告,这些问题可以由iframe来解决;
5)重载页面时不需要重载整个页面,只需要重载页面中的一个框架页;
6)方便制作导航栏。
缺点:
1)样式和脚本需要额外链入,调用外部页面,需要额外调用css,增加页面额外的请求次数,增加服务器的http请求;
2)代码复杂,在网页中使用框架结构最大的弊病是搜索引擎的“蜘蛛”程序无法解读这种页面,会影响搜索引擎优化,不利于网站排名;
3)框架结构有时会让人感到迷惑,滚动条除了会挤占有限的页面空间外会使iframe布局混乱,还会分散访问者的注意力,影响用户体验;
4)链接导航疑问。运用框架结构时,必须保证正确配置所有的导航链接,否则,会给访问者带来很大的麻烦。比如被链接的页面出现在导航框架内,这种情况下访问者便被陷住了,因为此时他没有其他地点可去;
5)产生多个页面,不易管理;
6)多数小型的移动设备(PDA 手机)无法完全显示框架,设备兼容性差。
7)iframes阻塞页面加载,影响网页加载速度
2. iframe与frame比较
1)frame不能脱离frameSet单独使用,iframe可以;
2)frame不能放在body中;
3)嵌套在frameSet中的iframe必需放在body中,不嵌套在frameSet中的iframe可以随意使用;
4)frame的高度只能通过frameSet控制;iframe可以自己控制,不能通过frameSet控制;
5)如果在同一个页面使用了两个以上的iframe,在IE中可以正常显示,在firefox中只能显示出第一个;使用两个以上的frame在IE和firefox中均可正常。
三、跨域
1.什么是跨域?
当一个请求url的协议、域名、端口三者之间的任意一个与当前页面url不同即为跨域。
https://www.cnblogs.com/hongplum
https://www.cnblogs.com/hongplum/p/14681987.html
没跨域 同源(协议、域名、端口号相同)
http://www.cnblogs.com/hongplum
https://www.cnblogs.com/hongplum
跨域 协议不同(http/https)
https://www.blog.com/hongplum
https://www.cnblogs.com/hongplum
跨域 主域名不同
https://blog.cnblogs.com/hongplum
https://www.cnblogs.t.com/hongplum
跨域 子域名不同(www/blog)
https://blog.cnblogs.com:80
https://blog.cnblogs.com:8080
跨域 端口号不同(80/8080)
2.跨域产生原因?(原文:https://blog.moonlet.cn/archives/563)
出于浏览器的同源策略限制。
同源策略(Same Orgin Policy)是一种约定,它是浏览器核心也最基本的安全功能,它会阻止一个域的js脚本和另外一个域的内容进行交互,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。。所谓同源(即在同一个域)就是两个页面具有相同的协议(protocol)、主机(host)和端口号(port)。
非同源会出现的限制
无法读取非同源网页的cookie、localstorage等
无法接触非同源网页的DOM和js对象
无法向非同源地址发送Ajax请求
3.解决跨域的方法
1)nginx反向代理解决跨域(前端常用)
正向代理:a=>c=>b
a-->b访问不了,可以找个中间的服务器c, 先访问c再从c到b,类似曲线救国。
明确访问的目的地,但是用户不知道中间的代理服务器。(忽略中间服务器)
反向代理:a=>c<=b
a明确访问c代理服务器,但是不知道c的内容从哪里来,c反向从别的地方拿来数据。(忽略的是目标地址)
浏览器可以访问a,而服务器之间不存在跨域问题,浏览器先访问a的服务器c,让c服务器作为代理去访问b服务器,拿到之后再返回数据给a。
例如:
nginx是静态服务器,跨域请求放在api下面好管理http://www.baidu.com:80/api/user
可以在nginx下面的config下面的nginx.conf里面配置从80端口进来的就拦截一下,代理到81端口
server{
location /api {
//拦截一下
proxy_pass http://www.baidu.com:81;
}
}
2)添加响应头解决跨域(常用)
header('Access-Control-Allow-Origin:*');//允许所有来源访问
header('Access-Control-Allow-Method:POST,GET');//允许访问的方式
3)通过jsonp解决跨域(老方法)
实现原理:通常为了减轻web服务器的负载,我们把js、css、图片等静态资源分离到另一*立域名的服务器上,在html页面中再通过script标签从不同域名下加载静态资源,而被浏览器允许。
优点
- 它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制,JSONP可以跨越同源策略;
- 它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持
- 在请求完毕后可以通过调用callback的方式回传结果。将回调方法的权限给了调用方。这个就相当于将controller层和view层终于分开了。我提供的jsonp服务只提供纯服务的数据,至于提供服务以 后的页面渲染和后续view操作都由调用者来自己定义就好了。如果有两个页面需要渲染同一份数据,你们只需要有不同的渲染逻辑就可以了,逻辑都可以使用同 一个jsonp服务。
缺点
- 它只支持GET请求而不支持POST等其它类型的HTTP请求
- 它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
- jsonp在调用失败的时候不会返回各种HTTP状态码。
- 安全性低,万一假如提供jsonp的服务存在页面注入漏洞,即它返回的javascript的内容被人控制的。那么结果是什么?所有调用这个 jsonp的网站都会存在漏洞。于是无法把危险控制在一个域名下…所以在使用jsonp的时候必须要保证使用的jsonp服务必须是安全可信的。
4)使用HTML5中新引进的window.postMessage方法来跨域传送数据
四、防抖和节流
窗口的resize、scroll,输入框内容校验等操作时,如果这些操作处理函数较为复杂或页面频繁重渲染等操作时,如果事件触发的频率无限制,会加重浏览器的负担,用户体验不好。可以采用debounce(防抖)和throttle(节流)的方式来减少触发的频率,同时又不影响实际效果。
1.防抖(debounce)
当持续触发事件时,debounce会合并事件且不会去触发事件,当一定时间内没有触发再这个事件时,才真正去触发事件
function debounce(fn, delay) {
var ctx;
var args;
var timer = null;
var later = function () {
fn.apply(ctx, args);
// 当事件真正执行后,清空定时器
timer = null;
};
return function () {
ctx = this;
args = arguments;
// 当持续触发事件时,若发现事件触发的定时器已设置时,则清除之前的定时器
if (timer) {
clearTimeout(timer);
timer = null;
}
// 重新设置事件触发的定时器
timer = setTimeout(later, delay);
};
}
效果:
2.节流(throttle )
throttle会合并一定时间内的事件,并在该时间结束时真正去触发一次事件
function throttle(fn, delay) {
var ctx;
var args;
// 记录上次触发事件
var previous = Date.now();
var later = function () {
fn.apply(ctx, args);
};
return function () {
ctx = this;
args = arguments;
var now = Date.now();
// 本次事件触发与上一次的时间比较
var diff = now - previous - delay;
// 如果隔间时间超过设定时间,即再次设置事件触发的定时器
if (diff >= 0) {
// 更新最近事件触发的时间
previous = now;
setTimeout(later, delay);
}
};
}
效果:
两者间的核心区别就在于持续触发事件时,前者合并事件并在最后时间去触发事件,而后者则是隔间时间触发一次~
五、数组里面有10万个数据,取第一个元素和第10万个元素的时间相差多少?
数组可以直接根据索引取的对应的元素,所以不管取哪个位置的元素的时间复杂度都是 O(1), 无论数据规模多大,都可以在一次计算后找到目标
\(\color{red}{得出结论:消耗时间几乎一致,差异可以忽略不计}\)
延伸
时间复杂度O(1),O(n), O(logn), O(nlogn)。算法时间复杂度有的时候说O(1), O(n), O(logn), O(nlogn),这是算法的时空复杂度的表示。不仅仅用于表示时间复杂度,也用于表示空间复杂度。O后面的括号中有一个函数,指明某个算法的耗时/耗空间与数据增长量之间的关系。其中的n代表输入数据的量。O描述的是算法的运行时间和输入数据之间的关系。
1.时间复杂度为O(1)。
- 是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。
\(\color{red}{哈希算法}\)就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标。
2.时间复杂度为O(n)。
- O(n)就代表数据量增大几倍,耗时也增大几倍。
比如常见的\(\color{red}{遍历算法}\)。 - O(n^2)就代表数据量增大n倍时,耗时增大n的平方倍,这是比线性更高的时间复杂度。
比如\(\color{red}{冒泡排序}\),就是典型的O(n^2)的算法,对n个数排序,需要扫描n×n次。
3.时间复杂度为O(logn)。
- 当数据增大n倍时,耗时增大logn倍(这里的log是以2为底的,比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度)。
\(\color{red}{二分查找}\)就是O(logn)的算法,每找一次排除一半的可能,256个数据中查找只要找8次就可以找到目标。
4.时间复杂度为O(nlogn)。
- 就是n乘以logn,当数据增大256倍时,耗时增大256*8=2048倍。这个复杂度高于线性低于平方。
\(\color{red}{归并排序}\)就是O(nlogn)的时间复杂度。
六、axios
1.axios、ajax和fetch区别
1)axios
通过promise实现对ajax技术的一种封装,就像jQuery实现ajax封装一样。
简单来说: ajax技术实现了网页的局部数据刷新,axios实现了对ajax的封装。
axios是ajax ajax不止axios。
优点:
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
axios({
url: 'http://jsonplaceholder.typicode.com/users',
method: 'get',
responseType: 'json', // 默认的
data: {
//'a': 1,
//'b': 2,
}
}).then(function (response) {
console.log(response);
console.log(response.data);
}).catch(function (error) {
console.log(error);
})
2)ajax
优点:
- 提高了性能和速度:减少了客户端和服务器之间的流量传输,同时减少了双方响应的时间,响应更快,因此提高了性能和速度
- 交互性好:使用ajax,可以开发更快,更具交互性的Web应用程序
- 异步调用:Ajax对Web服务器进行异步调用。这意味着客户端浏览器在开始渲染之前避免等待所有数据到达。
- 节省带宽:基于Ajax的应用程序使用较少的服务器带宽,因为无需重新加载完整的页面
- 底层使用XMLHttpRequest
- 拥有开源JavaScript库 : JQuery,Prototype,Scriptaculous等。
- AJAX通过HTTP协议进行通信。
缺点:
- 增加了设计和开发的时间
- 比构建经典Web应用程序更复杂
- Ajax应用程序中的安全性较低(容易收到CSRF和XSS攻击),因为所有文件都是在客户端下载的。
- 可能出现网络延迟的问题
- 禁用javascript的浏览器无法使用该应用程序
- 由于安全限制,只能使用它来访问服务于初始页面的主机的信息。如果需要显示来自其他服务器的信息,则无法在AJAX中显示。
$.ajax({
url: 'http://jsonplaceholder.typicode.com/users',
type: 'get',
dataType: 'json',
data: {undefined
//'a': 1,
//'b': 2,
},
success: function (response) {
console.log(response);
}
})
3)fetch
fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像$.ajax。但是,一定记住fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
优点:
- 符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象中
- 更好更方便的写法
- 更加底层,提供的API丰富(request,response)
- 脱离了XHR,是ES规范里新的实现方式
缺点:
- fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理
- fetch默认不会带cookie,需要添加配置项
- fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject和Promise.race结合setTimeout实现的超时控制并不能阻止请求过程继续在后台执行,造成了量的浪费
- fetch没有办法原生监测请求的进度,而XHR可以
try {
let response = await fetch(url);
let data = response.json();
console.log(data);
} catch(e) {
console.log("Oops, error", e);
}