目录
first-of-type和first-child有什么区别
JavaScript中什么是基本数据类型什么是引用数据类型?以及各个数据类型是如何存储的?
如果子组件直接修改父组件的值会发生什么?怎么解决,要修改多个数据怎么办?
devDependencies和dependencies的区别
Web标准以及W3C标准是什么?
标签闭后、标签小写、不乱嵌套、使用外链CSS和JS,结构行为表现的分离。
XHTML和HTML有什么区别?
- 一个是功能上的差别
主要是XHTML可兼容各大浏览器、手机以及PDA,并且浏览器也能快速正确地编译网页
- 另外就是书写习惯的差别
XHTML元素必须被正确地嵌套,闭合,区分大小写,文档必须拥有根元素。
语义化的理解
- 用正确的标签做正确的事件!
- HTML语义化就是让页面的内容结构化,便于对浏览器、搜索引擎解析。
- 在没有样式CSS情况下也以一种文档格式显示,并且是最容易阅读的。
- 搜索引擎的爬虫依赖于标记来确认上下文和各个关键字的权重,利用SEO。
- 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。
HTML5的离线存储怎样使用和工作原理是什么样的?
浏览器是怎么样对HTML5的离线存储资源进行管理和加载的?
描述下 cookies,sessionStorage和localStorage的区别?
对浏览器内核的理解
- 主要分成两部分:渲染引擎(layout engineer 或 Rendering Engine) 和 JS引擎
- 渲染引擎:负责取得网页的内容(HTML、XML、图像等),整理讯息(例如加入CSS等)。以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解析会有不同,所以渲染的效果也不相同。所以网页浏览器、电子邮件客户端以及其他需要编辑、显示网络内容的应用程序都需要内核。
- JS引擎:解释和执行JavaScript来实现网页的动态效果。
- 最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。
前端需要注意那些SEO
SEO的意思是“搜索引擎的优化”。
SEO具体是指通过网站结构调整、网站内容建设、网站代码优化、以及站外优化(网站站外推广、网站品牌建设等),使用网站满足搜索引擎的收录排名需求,提高网站在搜索引擎中关键字的排名,从而吸引精准用户进入网站,获得免费流量,生产直接销售或品牌推广。
- 合理的title、description、keywords,搜索对着三项的权重逐个减少。重要关键字出现不要超过2次,而且要靠前,不同页面title要有所不同;
- description把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面 description 有所不同;
- keywords 列举出重要关键词即可。
- 语义化的HTML代码,符合W3C规范:语义化代码让搜索引擎容易理解网页。
- 重要内容HTML代码块放在前面:搜索引擎抓取HTML顺序是从上到下的,有的搜索引擎对抓取长度有限制,保证重要内容一定会被抓取到。
- 重要内容不要用 js 输出:因为爬虫不会执行 js 获取的内容
- 少用 iframe :搜索引擎不会抓取 iframe 中的内容。
- 非装饰性图片必须加 alt
- 提高网站速度:网站速度是搜索引擎排序的一个重要指标
如果进行网站性能优化
- content 方面
- 减少HTTP请求:合并文件,css精灵图,inline Image
- 减少DNS查询:DNS缓存、将资源分布到恰当数量的主机名
- 减少DOM元素数量
- server 方面
- 使用CDN
- 配置ETag
- 对组件使用Gzip压缩
- cookie 方面
- 减少cookie大小
- css 方面
- 将样式表放到页面顶部
- 不使用CSS表达式
- 使用<link>不使用@import
- JavaScript 方面
- 将脚本放在页面底部
- 将JavaScript和CSS从外部引入
- 压缩JavaScript和CSS
- 删除不需要的脚本
- 减少DOM访问
- 图片方面
- 优化图片:根据实际颜色需要选择色深、压缩
- 优化CSS精灵
- 不要在HTML中拉伸图片
DOM
事件委托
//简易版:(有缺陷,没有考虑子元素)bug在于,如果用户点击的是li里面的psan。就没法触发fu,这是不对的。
ul.addEventListener('click', function(e) {
if(e.targer.tagName.toLowerCase() === 'li') {
fn() //执行某个函数
console.log('你点击了li')
}
})
//高级版,思路是点击span后,递归遍历span的祖先元素看其中有没有ul里面的li。
function delegate(element, eventType, selector, fu) {
element.addEventListener(eventType, e=> {
let el = e.target
while(!el.matches(selector)) {
if(element === el) {
el = null
break
}
el = el.parentNode
}
el && fn.call(el, e, el)
})
return element
}
虚拟DOM的优缺点
- 缺点
- 首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢
- 优点
- 减少了dom操作,减少了回流与重绘
- 保证性能的下限,虽说性能不是最佳,但是它具备局部更新的能力,所以大部分时候还是比正常的DOM性能高很多的
什么是DOM事件流?什么是事件委托
DOM事件流
- 分为三个阶段
- 捕获阶段
- 目标阶段
- 冒泡阶段
- 在addeventListener()的第三个参数(useCapture)设为true,就会在捕获阶段运行,默认是false冒泡
事件委托
- 利用冒泡原理(子向父一层层穿透),把事件绑定到父元素中,以实现事件委托
HTTP
HTTP的几种请求方法用途
HTTP协议中共定义了八种方法
1、GET 方法
发生一个请求来获取服务器上的某一资源
2、POST 方法
向URL指定的资源提交数据或附加新的数据
3、PUT 方法
跟POST方法很像,也是想服务器提交数据。但是,它们之间有不同。PUT指定了资源在服务器上的位置,而POST没有。
4、HEAD 方法
只请求页面的首部
5、DELETE 方法
删除服务器上的某资源
6、OPTIONS方法
它用于获取当前URL所支持的方法。如果请求成功,会有一个Allow的头包含类似“GET”“POST”这样的信息。
7、TRACE方法
TRACE方法被用于激发一个远程的,应用层的请求消息回路
8、CONNECT方法
把请求连接换成透明的TCP/IP通道。
GET和POST的区别(可能有误解)
- GET在浏览器回退时是无害的,而POST会再次提交请求
- GET产生的URL地址可以被加入收藏栏,而POST不可以
- GET请求会被浏览器主动cache,而POST不会,除非手动设置
- GET请求只能进行URL编码,而POST支持多种编码方式
- GET请求在URL中传送的参数是有长度限制的,而POST没有限制
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递重要信息
- GET参数通过URL传递,POST放在Request body中
简单来说,区别在于GET用于获取资源,POST用于提交资源
HTTP状态码及其含义
1xx:信息状态码
- 100 comtinue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息。
2xx:成功状态码
HTML
html5有那些新特性、移除了那些元素?
- HTML5现在已经不是SGML的子集,主要是关于图像、位置、存储、多任务等功能的增加。
- 绘画 canvas
- 用于媒介回放的video 和 audio 元素
- 本地离线存储 cocalstorage 长期存储数据,浏览器关闭后数据不丢失。
- sessionStrage 的数据在浏览器关闭后自动删除
- 语意化更好的内容元素,比如 article、footer、header、nav、section。
- 表单控件: calender、date、time、email、url、search。
- 新的技术:webworker、websocket、Geolocation。
- 移除的元素
- 纯表现的元素: basefont、big、center、font、s、strike、it、u
- 对可用性产生负面影响的元素: frame、frameset、noframes
- 支持HTML5新标签
- IE8/IE7/IE6支持通过 document.createElement 方法产生的标签
- 可以利用这一特性让这些浏览器支持HTML5新标签
- 浏览器支持新标签后,还需要添加标签默认的样式
- 当然也可以直接使用成熟的框架、比如html5 shim
CSS
为什么要初始化css样式?
因为浏览器的兼容问题,不同浏览器对有些标签的默认值不同,如果不初始化css,会导致不同浏览器页面间的显示差异。
常见的行内元素和块级元素都有哪些?
行内元素 inline
- 不能设置宽高,不能自动换行
- span、input、img、textarea、label、select
块级元素block
- 可以设置宽高,会自动换行
- p、h1/h2/h3/h4/h5、div、ul、li、table
inline-block
- 可以设置宽高,会自动换行
请说明px,em,rem,vw,vh,rpx等单位的特性
- px
- 像素
- em
- 当前元素的字体大小
- rem
- 根元素字体大小
- vw
- 100vw是总宽度
- vh
- 100vh是总高度
- rpx
- 750rpx是总宽度
link标签和import标签的区别
- link属于html,而@import属于css
- 页面被加载时,link会同时被加载,而@import引用的css会等到页面加载结束后加载。
- link是html标签,因此没有兼容性,而@import只有IE5以上才能识别。
- link方式样式的权重高于@import的。
first-of-type和first-child有什么区别
- first-of-type
- 匹配的是从第一个子元素开始数,匹配到的那个的第一个元素
- first-child
- 必须是第一个子元素
doctype
标签和meta
标签
- doctype
- 告诉浏览器以什么样的文档规范解析文档
- 标准模式和兼容模式
- 标准模式 ->正常,排版和js运作模式都是以最高标准运行
- 兼容模式->非正常
- meta
- <meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。
- <meta> 标签位于文档的头部,不包含任何内容。<meta> 标签的属性定义了与文档相关联的名称/值对。
- <meta> 标签提供关于 HTML 文档的元数据。它不会显示在页面上,但是对于机器是可读的。可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务。
meta标签的用法详解
script标签中defer和async都表示了什么
- 众所周知script会阻塞页面的加载,如果我们要是引用外部js,假如这个外部js请求很久的话就难免出现空白页问题,好在官方为我们提供了defer和async
- defer
-
<script src="d.js" defer></script> <script src="e.js" defer></script>
- 不会阻止页面解析,并行下载对应的js文件
-
下载完之后不会执行
-
等所有其他脚本加载完之后,在
DOMContentLoaded
事件之前执行对应d.js
、e.js
-
async
-
<script src="b.js" async></script> <script src="c.js" async></script>
- 不会阻止DOM解析,并行下载对应的js文件
- 下载完之后立即执行
DOMContentLoaded
事件- 是等HTML文档完全加载完和解析完之后运行的事件
- 在
load
事件之前。 - 不用等样式表、图像等完成加载
实现一个div在不同分辨率下的水平垂直居中
.box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid pink;
width: 100px;
height: 100px;
}
解释css sprites ,如何使用?
1、什么是精灵图
将一些小图标放在一张图上
2、精灵图的优点
减少图片的总大小
减少下载图片资源请求,减小建立连接的消耗
3、精灵图的使用方式
.icon1 {
background-image: url(css/img/sidebar.png);
background-repeat: no-repeat;
background-position: 20px 20px;
}
// 第一个数是x轴, 第二个数是y轴
box-sizing常用的属性有哪些?分别有什么作用?
- content-box
-
宽高是元素本身的宽高 不包含border+padding
-
-
border-box
-
元素的宽高已经包含了border+padding
-
-
inherit
-
从父元素继承box-sizing属性
-
CSS样式覆盖规则
!important > 内联样式 > id选择 > (class选择 = 伪类选择) > (标签选择 = 伪元素选择)
请简要描述margin重合问题,及解决方式
问题:相邻两个盒子垂直方向上的margin会发生重叠,只会取比较大的margin
解决:(1)设置padding代替margin
(2)设置float
(3)设置overflow
(4)设置position:absolute 绝对定位
(5)设置display: inline-block
对<meta></meta>标签有什么理解
1、meta是html文档头部的一个标签,这个标签对用户不可见,是给搜索引擎看的。
2、meta标签属性用法分成两大类
3、<meta charset="UTF-8"> 使用的编码格式,大部分是utf-8
display none ,visibility hidden区别?
居中为什么要使用transform(为什么不使用marginLeft/Top)
- transform 属于合成属性,不会引起整个页面的回流重绘,节省性能消耗,但是占用内存会大些
- top/left属于布局属性,会引起页面layout回流和repaint重绘。
重绘和回流(哪些情况重绘,哪些回流)
什么是BFC?
- BFC是一个独立渲染区域,它丝毫不会影响到外部元素
- BFC特性
- 同一个BFC下margin会重叠
- 计算BFC高度时会算上浮动元素
- BFC不会影响到外部元素
- BFC内部元素是垂直排列的
- BFC区域不会与float元素重叠
- 如何创建BFC
- position设为absolute或者fixed
- float不为none
- overflow设置为hidden
- display设置为inline-block或者inline-table或flex
如何清除浮动
- 额外标签clear:both
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.fahter{
width: 400px;
border: 1px solid deeppink;
}
.big{
width: 200px;
height: 200px;
background: darkorange;
float: left;
}
.small{
width: 120px;
height: 120px;
background: darkmagenta;
float: left;
}
.clear{
clear:both;
}
</style>
</head>
<body>
<div class="fahter">
<div class="big">big</div>
<div class="small">small</div>
<div class="clear">额外标签法</div>
</div>
</body>
- 利用BFC
- overflow:hidden
.fahter{
width: 400px;
border: 1px solid deeppink;
overflow: hidden;
}
- 使用after(推荐)
<style>
.clearfix:after{/*伪元素是行内元素 正常浏览器清除浮动方法*/
content: "";
display: block;
height: 0;
clear:both;
visibility: hidden;
}
.clearfix{
*zoom: 1;/*ie6清除浮动的方式 *号只有IE6-IE7执行,其他浏览器不执行*/
}
</style>
<body>
<div class="fahter clearfix">
<div class="big">big</div>
<div class="small">small</div>
<!--<div class="clear">额外标签法</div>-->
</div>
img 属性中的 title 和 alt 有什么区别
通常当鼠标滑动到元素上的时候显示。
alt 是 img属性 的特有属性,是图片内容的等价描述,用于图片无法加载时显示,读屏器阅读图片。可提高图片可访问性,除了纯装饰图片外都必须设置有意义的值,搜索引擎会重点分析。
正常盒模型和怪异盒模型的区别?
盒模型是CSS布局的基础,它的作用是规定了网页元素在网页上如何显示以及元素之间的相互关系,CSS定义所有的元素都可以拥有像盒子一样的外形和平面空间。即都包含内容区、补白(填充)、边框、边界(外边框)。
标准的盒模型:
- 内容区(content):元素的宽和高
- 补白(填充)(padding):元素内容和外边缘之间的空间
- 边框(border):盒子的外边缘
- 边界(外边距)(margin):盒子外边缘以外的空间
怪异的盒模型:
可以明显的看出,怪异盒模型的组成部分则只划分为两个部分:
- width/height(元素的内容宽度和高度):内容区(content)、补白(填充)(padding)以及边框(border)的总和。
- 边界(外边距)(margin):盒子外边缘以外的空间。
怪异盒模型的一个构成形式为元素的宽高包含了填充以及边框所占有的空间,也就是说当我们页面元素为怪异盒模型的时候,给予元素padding 或者 border 属性之后并不会改变元素原有宽度和高度的值,而如果我们给标准盒模型的元素添加padding 或者 border 属性 之后,元素最终的宽度和高度值会发送变化,盒子会变大,这也就是标准盒模型和怪异盒模型的区别所在。
box-sizing:border-box;/*转换成怪异盒模型*/
border-sizing:content-box;/*标准盒模型*/
介绍css3中position:sticky
position的含义是指定位类型,取值类型可以有:static
、relative
、absolute
、fixed
、inherit
和sticky
,这里sticky是CSS3新发布的一个属性。
- 设置了position: sticky的元素并不脱离文档流,仍然保留元素原本在文档流中的位置。
- 当元素在容器中被滚动超过指定的偏移值时,元素在容器内固定在指定位置。亦即如果你设置了top: 50px,那么在sticky元素到达距离相对定位的元素顶部50px的位置时固定,不再向上移动(相当于此时fixed定位)。
- 元素固定的相对偏移是相对于离它最近的具有滚动框的祖先元素,如果祖先元素都不可以滚动,那么是相对于viewport来计算元素的偏移量。
在web开发中注意兼容性:
sticky目前仍是一个试验性的属性,并不是W3C推荐的标准。它之所以会出现,也是因为监听scroll事件来实现粘性布局使浏览器进入慢滚动的模式,这与浏览器想要通过硬件加速来提升滚动的体验是相悖的。具体情况可以看下图,基本上可以说这个属性使用的浏览器只有FireFox
和iOS
的Safari
小程序自定义导航栏中使用sticky:
sticky是可以再小程序端生效的!
亲测这个属性在自定义导航时特别适用,我也是在纠结自定义导航的fixed适配占位问题时才了解到这个属性。
jS
数据类型
JavaScript中什么是基本数据类型什么是引用数据类型?以及各个数据类型是如何存储的?
基本数据类型有
- Number
- String
- Boolean
- Null
- Undefined
- Symbol(ES6新增数据类型)
- bigInt
引用数据类型统称为Object类型,细分的话有
- Object
- Array
- Date
- Function
- RegExp
基本数据类型的数据直接存储在栈中;而引用数据类型的数据存储在堆中,在栈中保存数据的引用地址,这个引用地址指向的是对应的数据,以便快速查找到堆内存中的对象。
顺便提一句,栈内存是自动分配内存的。而堆内存是动态分配内存的,不会自动释放。所以每次使用完对象的时候都要把它设置为null,从而减少无用内存的消耗。
类型转换
在JS中为什么0.2+0.1>0.3?
因为在JS中,浮点数是使用64位固定长度来表示的,其中的1位表示符号位,11位用来表示指数位,剩下的52位尾数位,由于只有52位表示尾数位。而0.1转为二进制是一个无限循环数 0.0001100110011001100......(1100循环)
由于只能存储52位尾数位,所以会出现精度缺失,把它存到内存中再取出来转换成十进制就不是原来的0.1
了,就变成了0.100000000000000005551115123126
,而为什么02+0.1是因为
// 0.1 和 0.2 都转化成二进制后再进行运算
0.00011001100110011001100110011001100110011001100110011010 +
0.0011001100110011001100110011001100110011001100110011010 =
0.0100110011001100110011001100110011001100110011001100111
// 转成十进制正好是 0.30000000000000004
判断数据类型有几种方法
-
typeof
- 缺点:
typeof null
的值为Object
,无法分辨是null
还是Object
- 缺点:
-
instanceof
- 缺点:只能判断对象是否存在于目标对象的原型链上
- constructor
- Object.prototype.toString.call()
-
一种最好的基本类型检测方式 Object.prototype.toString.call() ;它可以区分 null 、 string 、boolean 、 number 、 undefined 、 array 、 function 、 object 、 date 、 math 数据类型。
-
缺点:不能细分为谁谁的实例
-
// -----------------------------------------typeof
typeof undefined // 'undefined'
typeof '10' // 'String'
typeof 10 // 'Number'
typeof false // 'Boolean'
typeof Symbol() // 'Symbol'
typeof Function // ‘function'
typeof null // ‘Object’
typeof [] // 'Object'
typeof {} // 'Object'
// -----------------------------------------instanceof
function Foo() { }
var f1 = new Foo();
var d = new Number(1)
console.log(f1 instanceof Foo);// true
console.log(d instanceof Number); //true
console.log(123 instanceof Number); //false -->不能判断字面量的基本数据类型
// -----------------------------------------constructor
var d = new Number(1)
var e = 1
function fn() {
console.log("ming");
}
var date = new Date();
var arr = [1, 2, 3];
var reg = /[hbc]at/gi;
console.log(e.constructor);//ƒ Number() { [native code] }
console.log(e.constructor.name);//Number
console.log(fn.constructor.name) // Function
console.log(date.constructor.name)// Date
console.log(arr.constructor.name) // Array
console.log(reg.constructor.name) // RegExp
//-----------------------------------------Object.prototype.toString.call()
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(123)); // "[object Number]"
console.log(Object.prototype.toString.call("abc")); // "[object String]"
console.log(Object.prototype.toString.call(true)); // "[object Boolean]"
function fn() {
console.log("ming");
}
var date = new Date();
var arr = [1, 2, 3];
var reg = /[hbc]at/gi;
console.log(Object.prototype.toString.call(fn));// "[object Function]"
console.log(Object.prototype.toString.call(date));// "[object Date]"
console.log(Object.prototype.toString.call(arr)); // "[object Array]"
console.log(Object.prototype.toString.call(reg));// "[object RegExp]"
instanceof原理
- instanceof原理实际上就是查找目标对象的原型链
function myInstance(L, R) {//L代表instanceof左边,R代表右边
var RP = R.prototype
var LP = L.__proto__
while (true) {
if(LP == null) {
return false
}
if(LP == RP) {
return true
}
LP = LP.__proto__
}
}
console.log(myInstance({},Object));
typeof检测NaN返回什么?
首先NaN是‘not a number’ 的缩写。 表示“不是一个数字”。
通常会在一个数字和其他类型运算过程中产生:虽然他“不是一个数字”,但是NaN的typeof结果却是number。
console.log( typeof(4 * 'a' )); //number
NaN和任何变量都不相等,包括NaN自己。
console.log(NaN === NaN); //false
判断一个变量是不是NaN可以用 isNaN() 函数,但是这并不是一个完美的函数,有些时候同 value !== value 似乎更准确,ES6中已经有 Number.isNaN() 方法,将比isNaN准确的多。
typeof NaN !== NaN //返回 true
typeof undefined === undefined //返回false
typeof null //返回 object
typeof NaN === NaN //返回false
Naobj.currentStyle是只在ie浏览器里获取非行间样式
obj.getComputedStyle是在firefox、chorm、safari 浏览器都支持获取非行间样式
VUE
Vue数据响应式是什么样做到的?
- 在将一个普通的JavaScript对象传入Vue实例作为data选项,Vue将遍历此对象所有的Property,并使用Object.defineProperty把这些Property全部转为getter/setter。
- Vue不能检测到对象属性的添加或删除,解决方法是手动调用Vue.set或者this.$set
Vue双向绑定
数据劫持: vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()
来劫持各个属性的setter
,getter
,在数据变动时发布消息给订阅者,触发相应的监听回调
阐述一下你所理解的MVVM响应式原理
- vue是采用数据劫持配合发布者-订阅者的模式的方式,通过Object.defineProperty()来劫持各个属性的getter和setter,在数据变动时,发布消息给依赖收集器(dep中的subs),去通知(notify)观察者,做出对应的回调函数,去更新视图
- MVVM作为绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer,Compile之间的通信桥路,达到数据变化=>视图更新;视图交互变化=>数据model变更的双向绑定效果。
- data中每一个数据都绑定一个Dep,这个Dep中都存有所有用到该数据的观察者
- 当数据改变时,发布消息给dep(依赖收集器),去通知每一个观察者。做出对应的回调函数
const dep = new Dep()
// 劫持并监听所有属性
Object.defineProperty(obj, key, {
enumerable: true,
configurable: false,
get() {
// 订阅数据变化时,在Dep中添加观察者
Dep.target && dep.addSub(Dep.target)
return value
},
set: (newVal) => {
if (newVal !== value) {
this.observe(newVal)
value = newVal
}
// 告诉Dep通知变化
dep.notify()
},
})
watch和computed和methods区别是什么?
- computed和methods最大的区别在于computed有缓存,如果computed属性依赖的属性没有变化,那么computed属性就不会重新计算。methods则是看到一次计算一次。
- watch和computed相比,computed是计算出一个属性,而watch则可能是做别的事件。
Vue如何实现组件之间的通信
- 父子组件:使用v-on通过事件通信
- 爷孙组件:使用两次v-on通过爷爷爸爸通信,爸爸儿子通信实现爷孙通信
- 任意组件:使用eventBus = new Vue() 来通信和 eventBus.$emit 是主要API
- 任意组件:使用Vuex通信
- Vuex 里面的属性有:
- state
- 存储数据的
- 获取数据最好推荐使用getters
- 硬要使用的话可以用MapState, 先引用,放在compute中
...mapState(['方法名','方法名'])
- getters
- 获取数据的
- this.$store.getters.xxx
- 也可使用mapGetters 先引用,放在compute中,...mapGetters(['方法名','方法名'])
- mutations
- 同步操作数据的
- this.$store.commit(“方法名”,数据)
- 也可使用mapMutations ,使用方法和以上一样
- actions
- 异步操作数据的
- this.$store.dispatch(“方法名”,数据)
- 也可使用mapActions ,使用方法和以上一样
- modules
- 板块,里面可以放多个vuex
- state
- 父组件通过
v-bind:
/:
传值,子组件通过this.$attrs
获取- 父传子
- 当子组件没有设置props的时候可以使用
this.$attrs
获取到的是一个对象(所有父组件传过来的集合)
- 祖先组件使用provide提供数据,子孙组件通过inject注入数据
- parent/children
- refs—$ref
Vue的Key的作用
- key主要用在虚拟Dom算法中,每个虚拟节点VNode有一个唯一标识Key,通过对比新旧节点的key来判断节点是否改变,用key就可以大大提高渲染效率,这个key类似于缓存中的etag。
vue中父子组件的生命周期
- 父子组件的生命周期是一个嵌套的过程
- 渲染的过程
- 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
- 子组件更新过程
- 父beforeUpdate->子beforeUpdate->子updated->父updated
- 父组件更新过程
- 父beforeUpdate->父updated
- 销毁过程
- 父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
如果子组件直接修改父组件的值会发生什么?怎么解决,要修改多个数据怎么办?
如果修改的不是引用类型的值时会报错,告诉我们不能直接修改父组件的值。
(1)可以使用.sync修饰符来修改值,对一个 prop 进行“双向绑定”。(注意.sync 修饰符的 v-bind 不能和表达式一起使用)
(2)父组件将改变值的方法传递给子组件
vue的生命周期
- beforeCreate
- 创建之前,此时还没有data和Method
- Created
- 创建完成,此时data和Method可以使用了
- 在Created之后beforeMount之前如果没有el选项的话那么此时生命周期结束,停止编译,如果有则继续
- beforeMount
- 在渲染之前
- mounted
- 页面已经渲染完成,并且vm实例中已经添加完$el了,已经替换掉那些DOM元素了(双括号中的变量),这个时候可以操作DOM了(但是是获取不了元素的高度等属性的,如果想要获取,需要使用nextTick())
- beforeUpdate
- data改变后,对应的组件重新渲染之前
- updated
- data改变后,对应的组件重新渲染完成
- beforeDestory
- 在实例销毁之前,此时实例仍然可以使用
- destoryed
- 实例销毁后
Vue中的nextTick
- 解析
- nextTick : 在下次DOM更新循环结束之后执行延迟回调,在修改数据之后立即使用这个方法,获取更新后的DOM。
- 应用
- 需要在Vue生命周期函数中的 created() 操作DOM可以使用 Vue.nextTick() 回调函数
- 在数据改变后执行的操作,而这个操作需要等待数据改变后而改变DOM结构的时候才进行操作,需要用到 nextTick
批量异步更新策略及 nextTick 原理?
(1)批量异步策略
Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。
(2)nextTick
在下一次DOM更新循环结束之后执行延迟回调
computed和watch的区别
- computed
- 计算属性,依赖其他属性,当其他属性改变的时候下一次获取 computed 值时也会改变,computed 的值会有缓存
- watch
- 类似于数据改变后的回调
- 如果想深度监听的话,后面加一个 deep:true
- 如果想监听完立马运行的话,后面加一个 immediate:true
MVC与MVVM有什么区别
- MVC
- Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
- View(视图)是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
- Controller(控制器)是应用程序中处理用户交互的部分。
- 通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
- MVVM
- MVVM讲解
- 基于Vue实现一个简易MVVM
- 通过Object.defineProperty的get和set进行数据劫持
- 通过遍历data数据进行数据代理到this上
- 通过{{}}对数据进行编译
- 通过发布订阅模式实现数据与视图同步
diff算法
- diff算法是指对新旧虚拟节点进行对比,并返回一个patch对象,用来存储两个节点不同的地方,最后利用patch记录的消息局部更新DOM
- diff算法比较新旧虚拟dom
- 如果节点类型相同,则比较数据,修改数据
- 如果节点不同,直接干掉节点及所有子节点,插入新的节点
- 如果给每个节点都设置了唯一的key,就可以准确的找到需要改变的内容,否则就会出现修改一个地方导致其他地方都改变的情况。比如A-B-C-D, 我要插入新节点A-B-M-C-D,实际上改变的了C和D。但是设置了key,就可以准确的找到B C并插入
vue开发命令 npm run dev 输入后的执行过程
(1)npm run dev是执行配置在package.json中的脚本
(2)调用了webpack配置文件
(3)配置文件中调用了main.js
(4)main.js用到了一个html元素#app,引用路由等开始vue的模板编译
devDependencies和dependencies的区别
(1)devDependencies
用于本地开发,打包时生产环境不会打包这些依赖
(2)dependencies
开发环境能用,生产环境也能用。生产环境会被打包
Vue的优化方式
- v-if 和v-show
- 使用 Object.freeze() 方式冻结data中的属性,从而阻止数据劫持
- 组件销毁的时候会断开所有与实例联系,但是除了 addEventListener,所以当一个组件销毁的时候需要手动去 removeEventListener
- 图片懒加载
- 路由懒加载
- 为减少重新渲染和创建dom节点的时间,采用虚拟dom
Vue-router的模式
- hash模式
- 利用onhashchange事件实现前端路由,利用url中的hash来模拟一个hash,以保证url改变时,页面不会重新加载。
- history模式
- 利用 pushstate 和 replacestate 来将url替换但不刷新,但是有一个致命点就是,一旦刷新的话,就会可能404,因为没有当前的真正路径,要想解决这一问题需要后端配合,将不存在的路径重定向到入口文件。
Vue-router有哪几种钩子函数
- beforeEach
- 参数有
- to(Route路由对象)
- from(Route路由对象)
- next(function函数) 一定要调用才能进行下一步
- 参数有
- afterEach
- beforeRouterLeave
Vuex是什么?
Vuex是专门为vue.js应用程序开发的状态管理模式
单页面运用与多页面运用的不同,写项目怎么选择,为什么?
单页面应用(SPA) | 多页面应用(MPA) | |
组成 | 一个外壳页面和多个页面片段组成 | 多个完整页面构成 |
资源共用 | 共用,只需要在外壳部分加载 | 不共用,每个页面都需要加载 |
刷新方式 | 页面局部刷新或更改 | 整页刷新 |
url模式 | a.com/#/pageone a.com/#/pagetwo | a.com/pageone.html a.com/pagetwo.html |
用户体验 | 页面片段间的切换快,用户体验良好 | 页面切换加载缓慢,流畅度不够,用户体验比较差 |
转场动画 | 容易实现 | 无法实现 |
数据传递 | 容易 | 依赖url传递或者cookie、locaalStorage等 |
搜索引擎优化(SEO) | 需要单独方案,实现较为困难,不利于SEO检索,可利用服务器端渲染(SSR)优化 | 实现方法简易 |
试用范围 | 高要求的体验读,追求界面流畅的应用 | 适用于追求高度支持搜索引擎的应用 |
开发成本 | 较高,常需借助专业的框架 | 较低,但页面重复代码多 |
维护成本 | 相对容易 | 相对复杂 |
AJAX
- AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
- 什么是 AJAX ?
- AJAX = 异步 JavaScript 和 XML。
- AJAX 是一种用于创建快速动态网页的技术。
- 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
Webpack
webpack常用的几个对象及解释
-
entry 入口文件
-
output 输出文件
-
一般配合node的path模块使用
-
// 入口文件
entry:"./src/index.js",
output:{
// 输出文件名称
filename:"bundle.js",
// 输出的路径(绝对路径)
path:path.resolve(__dirname,"dist") //利用node模块的path 绝对路径
},
// 设置模式
mode:"development"
- mode 设计模式
-
module(loader)
-
里面有一个rules数组对某种格式的文件进行转换处理(转换规则)
-
use数组解析顺序是从下到上逆序执行的
-
module:{
// 对某种格式的文件进行转换处理(转换规则)
rules:[
{
// 用到正则表达式
test:/\.css$/, //后缀名为css格式的文件
use:[
// use数组解析顺序是从下到上逆序执行的
// 先用css-loader 再用style-loader
// 将js的样式内容插入到style标签里
"style-loader",
// 将css文件转换为js
"css-loader"
]
}
]
}
// -----------------------------------------------------vue的
module.exports={
module:{
rules:[
{
test: /\.vue$/,
use:["vue-loader"]
}
]
}
}
- plugin
- 插件配置
const uglifyJsPlugin = reqiure('uglifyjs-webpack-plugin')
module.exports={
plugin:[
new uglifyJsPlugin() //丑化
]
}
- devServer
- 热更新
devServer:{
// 项目构建路径
contentBase:path.resolve(__dirname,"dist"),
// 启动gzip亚索
compress:true,
// 设置端口号
port:2020,
// 自动打开浏览器:否
open:false,
//页面实时刷新(实时监听)
inline:true
}
-
resolve
-
配置路径规则
-
alias 别名
module.exports= {
resolve:{
//如果导入的时候不想写后缀名可以在resolve中定义extensions
extensions:['.js','.css','.vue']
//alias:别名
alias:{
//导入以vue结尾的文件时,会去寻找vue.esm.js文件
'vue$':"vue/dist/vue.esm.js"
}
}
}
- babel(ES6转ES5)
- 下载插件
babel-loader
,在module(loader)中配置
- 下载插件
loader和plugin的区别是什么?
- loader
- loader是用来解析非js文件的,因为Webpack原生只能解析js文件,如果想把那些文件一并打包的话,就需要用到loader,loader使webpack具有了解析非js文件的能力
- plugin
- 用来给webpack扩展功能的,可以加载许多插件