前端知识梳理
HTML 部分
h5新增了那些内容?
-
新元素
- 画布canvas
- 音频
audio
、视频video
- 新增语义标签
article nav footer section aside
等
-
新属性
- placeholder
- autofocus
- form等
-
新事件
- 拖放事件
- 窗口改变的事件(onresize)
-
取消了一些元素(font,center等)
-
新增DOCTYPE声明
-
完全支持css3
-
本地存储
语义化标签
-
什么是语义化标签
- 根据内容结构,选择合适的标签,便于开发和阅读,同时有利于爬虫更好的解析
-
为什么用
- 在没有css的情况下,页面也可以良好的展现页面的结构
- 更好的用户体验。
- 有利于SEO搜索引擎优化
- 方便其他设备的使用(比如屏幕阅读器、盲人阅读器)
- 便于开发维护
-
怎样用
- 尽可能的使用无语义化的标签
div
和span
- 在语义不明时,既可以使用div也可以使用p标签是,尽量使用p标签
- 不要使用纯样式标签比如b font u等,改用css设置
- 每个input标签对应的说明文本都需要使用label标签,并且通过为input设置id属性,在lable标签中设置for=someld来让说明文本和相对应的input关联起来。
- 尽可能的使用无语义化的标签
从前端的角度谈谈做好seo需要考虑什么
- 语义化标签
- 合理的添加 title 网页描述,关键词等
- 重要的html代码放在前面
- 少用iframe,搜索引擎不会抓取当中的内容
- 图片加上alt
文档类型
-
作用
- doctype声明位于文档的最前面,告知浏览器用的是哪种规范。如果不声明的话浏览器会进入quirks mode(混杂模式)
请描述一下 cookies,sessionStorage 和 localStorage 的区别?
-
cookie
- cookie是网站为了标识用户身份和存储在用户本地终端上的数据(一般经过加密处理)
- cookie数据始终在同源的http请求中携带,即会在浏览器和服务器之间相互传递
- 服务器可以主动添加cookie
-
sessionStorage和localStorage不会讲数据发送给服务器,仅仅保存在本地
-
存储大小
- cookie数据大小不超过4k
- sessionStorage和localStoreage可以达到5M或者更大(主要是各浏览器之间的区别)
-
存储时间
- localStorage是储存持久数据,浏览器关闭了不会丢失
- sessionStorage 浏览器关闭后自动删除
- cookie 设置过期时间之前一直有效,如果不设置则浏览器关闭自动删除
-
作用域不同
- sessionStorage相同的文档源的页面渲染在不同的标签中,数据是无法共享的。
- localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
canvas和svg的区别
- SVG
- svg是一种使用XML描述2D图形的语言
- svg基于SML,意味着svg DOM中的每个元素都是可用的,所以可以为每个元素添加js事件。
- 在svg中,每个被绘制的图像均被视为对象,如果svg对象的属性发生变化,那么浏览器能够自动的重现图像
- canvas
- 通过js来绘制2D图像
- canvas是逐像素进行渲染的
- 如果有地方发生改变那么整个图像都得重新绘制
- 区别
- canvas支持分辨率,svg不支持
- canvas不支持事件处理,svg支持
- canvas能够以.png 或者 .jpg格式保存文本
- svg渲染复杂度较高的程序会减慢渲染速(任何过度的使用dom的应该都不快)
- canvas适合图像密集型的游戏。
- canvas是基于位图的,svg是基于矢量图的。
- canvas绘制完成后不能使用脚本和css对其进行更改,而svg是文档对象模型的一部分,所以可以随时修改
src和href的区别
-
src是指向尾部资源的位置,用于替换当前元素,比如js脚本,图片等。
-
href指向网络资源所在的位置,用于应用建立连接确定之间的联系。
css部分
简述盒模型
盒模型由
content padding border margin
组成两个标准:标准盒模型和IE盒模型
-
两种盒模型的区别
- 标准盒模型认为宽高只是内容的宽高
- IE盒模型认为宽高是内容+内边距+边框的总宽高。
-
如何设置这两种盒模型?
-
css3的属性
box-sizing
//标准盒模型 box-sizing:content-box //IE盒模型 box-sizing:border-box
-
边距重叠的解决方案(BFC)
BFC块级格式化上下文。它是一个独立的渲染区域,规定和内部如何布局,并且这个区域和外部毫不相干
-
BFC原理
- 内部box会在垂直方向上一个接一个放
- box垂直方向的距离由margin决定。属于同一个BFC的两个相邻的margin会重叠。
- 每个元素margin box的左边,与包含border box左边相接触
- BFC的区域不会与float box重叠
- BFC就是页面上的一个独立的容器,容器里面的子元素不会影响到外面的元素,反之如此
- 计算BFC高度是,浮动元素也参与计算。
-
怎么创建BFC?
- float属性不为none时.
- position为absolute或者fixed
- display为inline-block table-cell,table-caption,flex,inine-flex
- overflow不为visible
- 根元素
-
应用场景
- 自适应两栏布局
- 清楚内部浮动
- 防止垂直margin重叠
清除浮动方法
- 使用带有
clear
属性的元素
.news {
background-color: gray;
border: solid 1px black;
}
.news img {
float: left;
}
.news p {
float: right;
}
.clear {
clear: both;
}
<div class="news">
<img src="news-pic.jpg" />
<p>some text</p>
<div class="clear"></div>
</div>
优点:简单代码少,浏览器的兼容好。
缺点:需要添加无语义的html元素,代码不够优雅,不利于维护。
-
使用CSS的overflow属性
触发BFC清楚浮动
.news { background-color: gray; border: solid 1px black; overflow: hidden; *zoom: 1; } .news img { float: left; } .news p { float: right; } <div class="news"> <img src="news-pic.jpg" /> <p>some text</p> </div>
-
使用CSS的:after伪元素
结合
:after
伪元素和IEhack,完美兼容各大主流浏览器..clearfix:after{ content: "020"; display: block; height: 0; clear: both; visibility: hidden; } .clearfix { /* 触发 hasLayout */ zoom: 1; }
css3选择器有哪些?
- 结构类型伪类选择器
- :first-child选择某个元素的第一个子元素;
- :last-child选择某个元素的最后一个子元素
- :nth-child()选择某个元素的一个或多个特定的子元素
- :nth-last-child()选择某个元素的一个或多个特定的子元素,从这个元素的最后一个子元素开始算
- :nth-of-type()选择指定的元素
- :nth-last-of-type()选择指定的元素,从元素的最后一个开始计算;
- :first-of-type选择一个上级元素下的第一个同类子元素;
- :last-of-type选择一个上级元素的最后一个同类子元素;
- :only-child选择的元素是它的父元素的唯一一个了元素;
- :only-of-type选择一个元素是它的上级元素的唯一一个相同类型的子元素;:empty选择的元素里面没有任何内容。
- 否定选择器
- :not
- 伪元素选择器
- ::first-line:选中元素的第一行
- ::first-letter:选中元素的第一个字母
- ::before和::after这两个主要用来给元素的前面或后面插入内容,通常和"content"一起配合使用,经常用来清除浮动。
JavaScript部分
ES6新特性
- 支持类
- 字符串模板
- 展开运算符
- 结构赋值
- 函数类
- 默认参数
- 不定参数
- 箭头参数
- let和const关键字
- generator
- pormises
- symbol
- poxy
Null和Undefined区别?
- null表示一个对象是“没有值”的值,也就是为空
- undefined表示一个变量声明了但是没有初始化(赋值)
- undefined不是一个有效的json值,而null是
- undefined的typeof的值是undefined,null的typeof的值是object
apply和call的用法和区别
-
用法
/*apply()方法*/ function.apply(thisObj,[arg1,arg2,arg3]) /*call()方法*/ function.call(thisObj,agr1,arg2,arg3);
-
共同点
- 代替一个对象调用一个方法,将一个函数,将一个函数的上下文从初始的上下文改为指定的新对象
- 如果没有提供新的this对象,则将使用全局对象
-
不同点
- apply最多只能有两个参数–新的this对象和一个数组。
- call可以接受多个参数,第一个与apply一样接受新的this对象。后面这是一串参数列表。
什么是闭包,闭包有什么作用?
- 闭包是指有权访问另一个函数作用域变量的函数。
- 作用
- 匿名自执行函数
(function(){...})()
创建一个匿名函数并且立刻执行,由于外部无法引用到它的内部变量,因此在执行完毕后就可以立刻被释放,不会污染全局变量 - 缓存可以保留函数内部的值
- 实现函数的封装
- 实现模板
- 匿名自执行函数
js有哪些基本类型?
- Undefined
- Null
- Boolean
- NaN
- String
- Number
Object是复杂数据类型
基本类型和引用类型的区别?
- 存储
- 基本类型值是在内存中占有固定大小的空间,因此是保存在栈内存中的
- 引用类型的值是对象,保存在堆内存中。包含引用类型的变量实际上并不是保存对象本身,而是指向该对象的一个指针。
- 复制
- 从一个变量向另一个变量复制基本类型的值,会创建该值得一个副本
- 从一个变量向另一个变量复制引用类型的值,复制的其实仅仅是指针,所以这两个变量始终都指向同一个对象。
- 检查类型
- 确定一个值是哪种基本类型可以使用
typeof
操作符 - 确定一个引用类型可以使用
instanceod
操作符
- 确定一个值是哪种基本类型可以使用
垃圾回收机制
js是一门具有自动垃圾回收机制的语言,开发人员不必要过于关心内存分配和回收的问题
- 离开作用域的值将会被标记为可以回收,因此在垃圾回收期间被删除
- “标记清除”是目前主流的垃圾收集算法,思路是给当前不使用的值加上标记,然后在回收
- 还有“引用计数”这种算法是跟踪记录所有值被引用的次数,如果引用次数为0就将其删除
javascript的DOM是什么意思?
DOM是W3C的对象模型,DOM是中立与平台和语言的接口,它允许程序脚本动态的访问和更新文档结构和样式
javascript继承的方法?
- 原型链继承
- 借用构造函数继承
- 组合继承(原型+借用构造函数)
- 原型式继承
- 寄生式继承
- 寄生组合式继承
Promise对象是什么?
promise是ES6对于异步编程提供的一种解决方案,比传统的解决方案(回调函数和事件)更加合理
-
传统回调
// 当参数a大于10且参数func2是一个方法时 执行func2 function func1(a, func2) { if (a > 10 && typeof func2 == 'function') { func2() } } func1(11, function() { console.log('this is a callback') })
-
Promise改写
function fun1(a) { return new Promise((resolve, reject)=>{ if(a>10){ resolve(a) }else { reject('b') } }) } fun1(7) .then(res =>{ console.log('cj') }) .catch(err=>{ console.log(err) })
-
promise对象的两个特点
- 对象的状态不受外界的影响,有三种状态:
- pending(进行中)
- fulfilled(已成功)
- reject(已失败)
- 一旦状态改变,就不会再改变
- 从pending到fulfilled
- pending到rejected
- 对象的状态不受外界的影响,有三种状态:
-
Promise对象实例的两个参数
- resolve:将promise状态从未完成变成完成。在异步操作成功时,将异步操作的结果作为参数传递出去
- reject:将promise对象的状态从未完成转变成失败。在异步操作失败的时候调用,并将错误作为参数传递出去
-
promise对象的实例方法
- then方法:用于指定调用成功时的回调函数,then方法返回的是一个新的promise实例。因此可以采用链式写法,即在then后面再调用一个then
- catch方法:用于指定错误发生时的回调函数。
async和await
axios、fetch、ajax有什么区别?
主要的区别就是axios、fetch都支持promise对象的API,ajax只能使用回调函数。
- axios
- 是一个基于promise的http库,支持promise所有的API
- 它可以拦截请求和响应。
- 它可以转换请求数据和响应数据,并且对响应回来的数据自动转换成JSON数据
- 安全性更高,客户端支持防御XSRF
判断数组的方法
let arr = [1,2,3,4,5];
//第一种
Object.prototype.toString.call(arr) // "[object Array]"
//第二种
Arr.isArray(arr) // true
//第三种
arr instanceof Array // true
//第四种
arr.constructor === Array //true
数组有哪些方法?
-
join()
将数组的元素组成起来变成一个字符串,接受一个参数即分隔符,如果省略参数则用逗号代替
-
push()和pop()
- push() 可以接受任意数量的参数 ,返回修改后数组的长度
- pop() 数组尾部移除最后一项,然后返回移除的项
-
shift()和unshift()
- shift()删除原来数组的第一项,返回删除的值,如果为空则返回undefined
- unshift()将参数添加到数组的第一项,并且返回新数组的长度
-
sort()
按照升序排列数组项,也可以传递一个比较函数来控制是升序还是倒叙排列
-
reverse()
反转数组的顺序
-
concat()
将参数添加到原数组中,返回新创建的数组。
-
slice()
返回原数组中指定开始下标到结束下标之间的新数组。接受两个参数,即开始和结束位置,如果只有一个参数时,结束位置到当前数组的末尾。如果有两个参数,则返回起始位置和结束位置之间的项目,但是不包括结束位置
-
splice()
可以实现删除,插入和替换。
参数 描述 index 必须。整数,规定添加或者、删除的位置,使用负数的话从尾部开始算 howmany 必须。要删除的项目的数量。如果为0则表示不删除 item1,…, itemx 可选,向数组添加的新项目 始终都会返回一个新数组,返回删除后的值,如果没有删除值则返回空。该方法会修改原数组。
-
indexOf()和lastIndexOf()
-
这两个方法都返回要查找的项在数组的中位置,没有找到则返回-1
-
indexOf() 接受两个参数,要查找的项和查找开始的起点(可选)
-
lastIndexOf() 同上,区别是从数组的最后一项开始查找。
-
-
forEach
对数组进行遍历循环,对数组中的每一项运行给定函数,本身没有返回值。参数为function类型,参数为数组的内容,对应的索引,数组的本身。
-
map()
指映射,对数组中的每一项运行给定的函数,返回每次函数调用的结果组成的数组。
-
filter()
过滤功能。数组中的每一项都运行给定的函数,返回满足过滤条件组成的数组。
-
every()
判断数组中每一项是否都满足条件,只有都满足条件才返回true
-
some()
判断数组中是否有满足条件的项,有的话返回true
-
reduce()和reduceRight()
这两个方法都会迭代数组的所有项,然后构建一个最终返回值。
这两个方法都接受两个参数,在每一项是哪个调用的函数和作为归并基础的初始值(可选)
深拷贝和浅拷贝的区别以及如何实现
假设B复制了A,当修改A时,如果B发生了变化,那就是浅复制,如果没有发生变化就是深复制。
-
为什么会出现这种情况?
- 数据类型分为:引用类型和基本类型
- 引用类型的名存在栈内存中,值存在于堆内存中
- 基本类型名值都存在于栈内存中
- 引用类型进行正常的复制拷贝时,只复制了引用地址,并非栈里面的值。
-
如何实现深拷贝?
let obj = { a:34, b:5, c:{ a:2, b:54 } } //深拷贝 //使用JSON对象的parse和stringify 先将对象转成字符串形式,再转存过来赋值 let deep = JSON.parse(JSON.stringify(obj)) //递归实现深拷贝 function deep(obj){ let clone = Array.isArray(obj) ? [] : {}; for(let key in obj){ if(obj.hasOwnProperty(key)){ //判断子元素时候是引用类型,是的话使用递归继续拷贝 if( obj[key] && typeof obj[key] === 'object'){ clone[key] = deep(obj[key]) }else { clone[key] = obj[key] } } } return clone }
VUE部分
对于Vue是一套渐进式框架的理解
- 主张最少,没有多做职责之外的事情
vue.js的两个核心是什么?
-
数据驱动(双向数据绑定)
vue数据观测实现原理是利用
Object.defineProperty
和储存器属性 -
组件系统
- 模板
- 初始化数据
- 接受外部参数
- 方法
- 生命周期函数钩子
- 私有资源
Vue几种常用的指令
- v-if:根据表达式的真假渲染元素,在切换时元素及其它的数据绑定(组件)会被销毁并重建
- v-show:根据表达式的真假,切换元素的display css属性
- v-for:循环指令,基于一个对象或者数组渲染一个列表,vue2.0以上必须配个key值
- v-bind:动态的绑定一个或者多个特性,或者一个组件prop到表达式
- v-on:用于监听指定元素的dom事件,比如点击事件
- v-mode:实现表单输入和应用之间的双向绑定
- v-pre:跳过这个元素和它的子元素的编译过程,跳过大量没哟指令的节点可以加快编译
- v-once:只渲染元素和组件一次。随后的重新渲染将被视为静态内容并且跳过,可以用来优化性能。
v-if和v-show的区别
- 共同点
- 都是动态的现实隐藏dom
- 却别
- 编译过程
- v-if是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器、子组件适当的被销毁和重建。
- v-show的元素始终会被渲染并且保留在DOM中。只是简单的切换元素的css属性display
- 编译条件
- v-if是惰性的,如果在初始化时候渲染条件为假,则说明也不做,直到第一次为真时才开始真正的渲染
- v-show不管初始条件是说明,元素总是会被渲染
- 性能消耗
- v-if有更高的切换消耗,v-show有更高的初始渲染消耗
- 应用场景
- v-if适合运行时条件很少变动的使用,v-show适合频繁切换的使用
- 编译过程
v-0n可以监听多个方法吗?
-
可以监听多个方法
<input type="text" :value="name" @input="onInput" @focus="onFocus" @blur="onBlur" />
-
但是同一种事件类型会报错
//报错 <`a href="javascript:;" @click="methodsOne" @click="methodsTwo"></a>
vue中key值得作用
key值用于管理可复用的元素。因为vue会尽可能高效的渲染元素,通常会复用已有元素,而不是从头渲染。
但是如果两个元素是相互独立,不需要复用他们。只需要添加一个
key
即可
$nextTick的使用
因为vue的异步更新队列,
$nextTick
是用来知道什么时候DOM更新完成的。
- 异步更新队列
- vue在观察到数据发生变化的时候不是直接的更新DOM, 而是开启一个队列,并且在缓冲在同一个时间循环中发生的数据改变,去除重复数据,从而避免不必要的计算和DOM更细。
<div id="app">
<div id="div" v-if="showDiv">这是一段文本</div>
<button @click="getText">获取div内容</button>
</div>
<script>
var app = new Vue({
el : "#app",
data:{
showDiv : false
},
methods:{
getText:function(){
this.showDiv = true;
var text = document.getElementById('div').innnerHTML;
console.log(text);
}
}
})
//这里会抛出错误,获取不到div元素,原因就是异步更新队列的存在
使用$nextTick
处理
<div id="app">
<div id="div" v-if="showDiv">这是一段文本</div>
<button @click="getText">获取div内容</button>
</div>
<script>
var app = new Vue({
el : "#app",
data:{
showDiv : false
},
methods:{
getText:function(){
this.showDiv = true;
this.$nextTick(function(){
var text = document.getElementById('div').innnerHTML;
console.log(text);
});
}
}
})
Vue组件中为什么data必须是函数?
- 因为组件是可以共享的,但是他们的data是私有的,所以每个组件都要return一个新的data对象,返回一个唯一的对象,不能喝其他组件共享一个对象
Vue中keep-alive组件的作用?
主要用于保留组件状态或者避免重新渲染。
-
包裹动态组件,会缓存不活动的组件实例,而不是去销毁他们。
-
include
和exclude
属性允许组件有条件的进行缓存 -
用法
<!-- 基本 --> <keep-alive> <component :is="view"></component> </keep-alive> <!-- 多个条件判断的子组件 --> <keep-alive> <comp-a v-if="a > 1"></comp-a> <comp-b v-else></comp-b> </keep-alive> <!-- 和 `<transition>` 一起使用 --> <transition> <keep-alive> <component :is="view"></component> </keep-alive> </transition> <!-- 逗号分隔字符串 --> <keep-alive include="a,b"> <component :is="view"></component> </keep-alive> <!-- 正则表达式 (使用 `v-bind`) --> <keep-alive :include="/a|b/"> <component :is="view"></component> </keep-alive> <!-- 数组 (使用 `v-bind`) --> <keep-alive :include="['a', 'b']"> <component :is="view"></component> </keep-alive>
Vue的生命周期相关
vue实例从创建到销毁的一些列过程,在这个过程会运行一些叫做生命周期函数的钩子。给用户在不同的阶段添加自己代码的机会。
钩子函数 详情 beforeCreate 在实例初始化后,数据观测和事件配置之前被使用 created 在实例化创建完成后立刻被调用,已经完成数据观测,属性和方法的运算、事件回调。但是挂载阶段还没有开始。$el属性目前不可以使用 beforeMount 在挂载开始之前被调用,相关的render函数首次被调用 mounted el被新创建的vm.$el替换,并挂载到实例上去之后,调用该钩子 beforeUpdate 数据更新前调用,发生在虚拟DOM打补丁之前。该钩子函数在渲染器不被调用 updated 数据更新后调用。在渲染期不被调用 actived keep-alived
组件激活时候被调用.在渲染期不被调用beforeDestroy 实例销毁之前调用,在这一步实例仍然完全可以用,在渲染期不被调用 destroyed 实例销毁后被调用,调用后vue实例指示的所有组件都会被解绑。在服务器渲染期不被调用
Vue中对象更改检测的注意事项
由于javascript的限制,Vue不能检测对象属性的删除和添加,对于已经创建的实例,vue不能动态的添加根级别的响应式属性,但是可以使用
Vue.set(obj,key,value)
方法嵌套对象,添加响应式属性。
var vm = new Vue({
data:{
user:{
name:jason
}
}
})
//添加新的属性给user对象
Vue.set(vm.user,'age',35)
//如果需要添加多个属性的话
vm.user = Object.assign({},vm.user,{
height:'175cm',
like:'sleep'
})
Vue等单页面应用的优缺点
单页应用:就是只有一张web页面的应用。SPA是加载单个HTML页面并在用户与应用程序交互时动态更新页面的web应用程序。对于单页应用来说模块化的开发和设计显得相当的重要
- 单页应用的优点:
- 提供了更加吸引人的用户体验,具有桌面应用的即时性,网站的可移植新和可访问性
- 单页应用的内容改变不需要重新加载整个页面。
- 单页应用没有页面间的跳转,就不会出现白屏现象,也不会有假死和闪烁现象
- 单页应用对于服务器的压力较小,服务器只管出数据就可以,不用管暂时逻辑和页面合成。吞吐能力提高几倍
- 良好的前后端分离,后端不再负责页面渲染、页面输出工作,后端API通用化,即后端程序同一套代码,不用修改就可用于web端、手机端、平板端等多种客户端。
- 缺点
- 首次加载耗时比较多
- SEO问题,不利于百度谷歌搜索引擎收录
Vue中自定义指令
-
自定义指令的几个钩子函数
bind
只调用一次,指令第一次绑定到元素的时候调用,在这里可以进行初始化操作inserted
被绑定元素插入父节点时调用update
所在组件的VNode更新前调用componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind
只调用一次,组件解绑时候调用
-
钩子函数的参数
除了
el
之外,其它参数都应该是只读的,切勿进行修改。如果要在钩子之间共享数据,建议通过元素的dataset来进行- el:指令所绑定的元素,可以用来直接操作DOM
- binding:一个对象,包含以下属性
- name:指令名称
- value:指令绑定的值
- oldValue:指令绑定的前一个值,仅仅在update和componentUpdated 钩子中使用
- ···expression:字符串形式的指令表达
- arg:传给指令的参数,可选
- modifiers:一个包含修饰符的对象。
父组件异步获取动态数据传递给子组件?
- 利用
v-if
可以在http请求返回后再显示。
Vue中各种情况的组件之间的通讯
-
父子组件通讯
- 父子之间可以总结为:prop向下传递,事件向上传递。
-
非父子之间的传值
-
非父子组件之间的通讯需要定义一个公共文件
bus.js
,作为中间仓库来传值。//公共bus.js import Vue from 'vue' export default new Vue() //组件a <template> <div> A组件: <span>{{elementValue}}</span> <input type="button" value="点击触发" @click="elementByValue"> </div> </template> <script> // 引入公共的bug,来做为中间传达的工具 import Bus from './bus.js' export default { data () { return { elementValue: 4 } }, methods: { elementByValue: function () { //触发事件 Bus.$emit('val', this.elementValue) } } } </script> //组件B <template> <div> B组件: <input type="button" value="点击触发" @click="getData"> <span>{{name}}</span> </div> </template> <script> import Bus from './bus.js' export default { data () { return { name: 0 } }, mounted: function () { var vm = this // 用$on事件来接收参数 Bus.$on('val', (data) => { console.log(data) vm.name = data }) }, methods: { getData: function () { this.name++ } }, destroyed(){ //在组件销毁时,一定要解绑事件.不然会出现一些不可预知的事情 Bus.$off('val') } } </script>
-
VueX
-
什么是VueX?
- vuex是转为Vue.js应用程序开发的状态管理器,采用集中存储,管理应用的所有组件的状态
-
使用VueX的核心概念?
- 每个VueX应用的核心就是store(仓库),基本上就是一个容器,包含着你的应用中大部分的状态(state)
-
vuex和单纯的全部对象有一下不同:
- vuex的状态存储是响应式的,当vue组件从store中读取状态的时候,楼store中的状态发生变化,那么下面还有的组件也会等到高效的更新。
- 不能直接改变store中的状态,改变store中状态唯一的途径就是显式的提交(commit)mutation,这样使得我们可以方便的跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好的了解我们的应用。
React
React的概述?
- 功能
- 它使用的是虚拟DOM,而不是正真的DOM。
- 它可以进行服务器端渲染
- 它遵循的是单向数据流
- 主要优点
- 提高了应用的性能。
- 可以方便的在服务器端使用
- 使用jsx,代码的可读性很高
- 编写UI测试用例变得非常的容易
- 什么是jsx
- jsx是JavaScript XML的简写,在JavaScript里面写类似HTML的模板语法
- 什么是虚拟DOM,它的工作原理是什么?
- 虚拟DOM是一个轻量级的JavaScript对象,初始化的时候是真实Dom的一个副本。是一个节点树,他将元素及他们的属性和内容作为对象及其属性。React的渲染函数从react组件中创建一个节点树,然后它响应节点。
- 虚拟DOM工作过程有三个简单的步骤。
- 每当底层数据发生变化的时候,整个UI都将在虚拟DOM描述中重新渲染
- 然后计算之前DOM表示与新表示之间的差异
- 计算完成后,讲只用实际更改的内容更新真实DOM
其他部分
性能优化
- 网页内容
- 减少http请求次数
- 捆包文件——将多个js或者css困成单个文件,减少请求次数
- 将小图片转换成base64编码内嵌到网页文本中。
- 减少DNS查询次数
- 避免页面跳转
- 缓存ajax
- 延时加载
- 进入页面是置加载必须的内容,剩下的内容可以推迟到延时加载中
- 提前加载
- 提前加载接下来网页中访问的资源。
- 减少DOM元素数量
- 复杂的页面意味着要下载更多的直接,意味着javascript中DOM访问速递变得更慢。
- 根据域名划分内容
- 刘浏览器对同一个域的下载链接数有所限制,叫做浏览器并发请求数,所以按照域名进行划分下载内容就可以让浏览器增大并发下载数,但是也要控制好数量,不然DNS查询也是个问题
- 减少iframe数量
- iframe优点:
- 可以用来加载速度较慢的内容,比如广告
- 安全沙箱保护,浏览器会对iframe中的内容进行安全控制
- 脚本可以并行下载
- iframe缺点
- 即时iframe内容为空也消耗下载时间
- 会组织页面加载
- 没有语言
- 对seo不友好
- iframe优点:
- 避免404
- 减少http请求次数
- 服务器
-
使用CDN加速
- 用户与WEb服务器的距离会对响应时间产生影响。在多个地理位置分散的服务器上部署内容将使您的页面从用户角度加载更快。
-
添加cache-control或者expire报文头
浏览器和代理使用缓存来减少HTTP的数量和大小,从而加快网页的加载速度。
web服务器使用http响应中的expire头来告诉客服端可以缓存组件资源多久。比如
Expires:Thu,15 Apr 2019 20:00:00 GMT //表示在2019-04-15前都可以缓存该资源
- 对于静态组件:通过添加expire头实现“永不过期”策略
- 对于动态的组件:使用适当的cache-control头来帮助浏览器处理请求
-
Gzip压缩传输文件
从HTTP1.1开始支持Access-Encoding进行压缩
Accept-Encoding:gzip,deflate
gzip一般可以减少响应的70%
-
配置ETags
-
实体标记ETag使web服务器和浏览器用于确定浏览器缓存中的组件是否与源服务器上组件匹配的机制。添加ETag以提供验证比上次修改日期更灵活的机制。
//服务器端设置 HTTP/1.1 200 OK Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT ETag: "10c24bc-4ab-457e1c1f" Content-Length: 12195
-
浏览器要是需要验证组件,用
If-None-Match
头部来传递ETag给服务器。如果ETag匹配,则服务器返回304//浏览器端设置 GET /i/yahoo.gif HTTP/1.1 Host: us.yimg.com If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT If-None-Match: "10c24bc-4ab-457e1c1f" HTTP/1.1 304 Not Modified
-
-
使用GET Ajax请求
- 在使用
XMLHttpRequuest
时,POST在浏览器中实现为两步过程,首先发送头部,然后在发送数据。但是GET只要发送一次。但是在IE中最大url长度为2k,如果长度超过则可能无法发送。
- 在使用
-
避免空的图片src
-
- Cookie
-
减少cookie的大小
- cookie的信息通过http头部在浏览器和服务器端相互交换,尽量减少cookie大小来降低响应时间
-
页面内容使用无cookie域名
当浏览器在发出静态图像并请求cookie与请求一起发送时,服务器对这些cookie没有任何的用处,这些都属于白白浪费的流量
- 如果您的域名是
www.example.com
,您可以托管您的静态组件在域名static.example.com
上。但是如果您在顶级域名上设置了cookie,那么所有的请求都会包含这些cookie。
- 如果您的域名是
-
- CSS
- 将样式表置顶
- 将样式表已到文档的HEAD会使得页面看起来加载速度变快。这是因为样式表放在HEAD中允许页面逐步呈现。
- 避免使用css表达式
- css表达式是强大的,但是问题在于它的计算评率大大的高出了人们的预期,大量的计算知道页面卡顿。
- 用link代替@inport
- 在IE用
@import
和把css放在底部行为一直,所以最好别用。
- 在IE用
- 避免使用fittlers
- 专用的
AlphaImgeLoader
过滤器旨在解决IE版本低于7的半透明真彩色PNG的问题。该过滤器的问题在于他在下载图像时候阻止页面渲染并且冻结浏览器。增加内存的消耗,并且每个元素用于而不是每个图像。因此问题成倍增加。 - 最佳的做法是放弃这个过滤器,使用PNG8来优雅降级。
- 专用的
- 将样式表置顶
- javascript
- 将脚本置底
- 脚本引起的问题是他们阻塞了并行下载。当浏览器在下载脚本,就不会下载其他的组件,即时在不同的组件下。如果脚本中运用了
docum.write
来插入内容,他就不能被移到底部。 - 建议使用异步脚本。
defer
属性表明脚本不包含document.write。
- 脚本引起的问题是他们阻塞了并行下载。当浏览器在下载脚本,就不会下载其他的组件,即时在不同的组件下。如果脚本中运用了
- 使用外部的javascript和css
- 因为浏览器会缓存javascript和css文件。
- 精简javascript和css
- 压缩代码就是删除代码中不必要的字符来减小文件大小,从而提高加载速度。
- 去除重复的脚本
- 减少DOM的访问
- 缓存访问过的元素的引用
- 在DOM树外更新节点,然后添加到DOM树种
- 避免使用js实现固定布局
- 使用事件代理
- 使用事件委托来绑定事件将极大的提高js性能
- 将脚本置底
- 图片
- 优化图像
- 图像格式的转化,可以将非动画的gif格式转化为png格式的图片
- 优化css sprite
- 不要在HTML中缩放图片
- 使用小且可以缓存的faviocon.ico
- 优化图像
HTTP状态码
-
1**(信息类):表示接收到请求并且继续处理
- 100——客户端必须继续发出请求
- 101——客户端要求服务器根据请求转换http协议版本
-
2** (响应成功类):表示请求被成功接收、理解和接收
- 200———表明该请求被成功完成,所请求的资源以返回客户端
- 201——提示知道新文件的URl
- 202——接受和处理,但处理并没有完成。
- 203——返回信息不完成或不确定
- 204——请求收到,但是返回信息为空
- 205——服务器完成请求,用户代理必须复位当前已经浏览过的文件
- 206——服务器已经完成部分用户的get请求
-
3** (重定向类):表示完成了指定的动作,必须接受进一步处理
- 300——请求的资源可以在多处得到
- 301——本网页被永久性的转移到另一个URL
- 302——请求的资源被转移到新的地址上(临时重定向)
- 303——建议客户端访问其他url或访问方式
- 304——自从上次访问过后资源从未被修改过,可以直接使用缓存
- 305——请求的资源必须从服务器指定的地址得到
- 306——前一版本HTTP中使用的代码。现在版本中中已经不在使用
- 307——声明请求的资源临时性删除
-
4** (客户端错误类):请求包含语法错误或者不能正确的执行
- 400——客户端请求的语法错误,不能被服务器接受理解
- 401——请求未经过授权
- 402——保留有效的chargeTo头响应
- 403——访问禁止,服务器收请求,但是拒绝访问
- 404——表明可以连接服务器,但是服务器无法取得所请求的资源,请求的资源不存在。
-
5** (服务器错误类)
- 500——服务器不能正确的执行一个正确的请求
- 502——网关错误
- 503——由于超载或停机维护,服务器目前无法使用,一段时间后恢复正常
get请求和post请求的却别?
-
get请求在浏览器退回的时候是无害的,因为浏览器会缓存get请求的数据,而post请求不会被缓存,所以在post请求在退回时会再次提交请求(除非主动设置)。
-
get的请求产生的地址可以被存入书签,而post不可以。
-
get请求的只能进行url编码,而post可以支持多种编码方式
-
get请求在url中传输是有大小限制的,大约为2k(具体浏览器不一样),而post存放在body中,所以没有大小限制
理论上可以玩url上塞无限的参数,但是由于浏览器和服务器的限制,数据量太大会增大负担,所以大多数参数超过2kb直接不处理。
-
get将参数暴露在url上,所以一般不用于传递敏感信息。
-
get请求只产生一个数据包,而post需要发送两次。