前端面试题
- 一、HTML 5
- 二、CSS3
- 三、JavaScript
- 四、JavaScript高级
- 五、ES6
- 六、Vue
- 1. 说说你对MVVM的理解
- 2. Vue2.x响应式数据/双向绑定原理
- 3. 你知道Vue3的数据响应式原理吗?
- 4. v-model双向绑定原理?
- 5. Vuex是什么,什么情况下用?
- 6. Vuex和单纯的全局对象有什么区别?
- 7. 说一下v-if和v-show的区别?
- 8. 为什么 v-for 和 v-if 不建议用在一起?
- 9. 组件中的data为什么是函数?
- 10. watch、computed 和 methods 的区别?
- 11. Vue 路由模块中 $route 和 $router 的区别?
- 12.如何实现跨域?
- 13.vue组件之间如何进行通信?
- 14.Vue-router 中hash模式和history模式的区别?
- 15.v-for循环为什么一定要绑定key?
一、HTML 5
1.HTML文件中的DOCTYPE是什么作用?
- HTML超文本标记语言: 是一个标记语言, 就有对应的语法标准
- DOCTYPE 即 Document Type,网页文件的文档类型标准。
- 主要作用是告诉浏览器的解析器要使用哪种 HTML规范 或 XHTML规范 来解析页面。
// DOCTYPE 需要放置在 HTML 文件的 <html> 标签之前,如:
<!DOCTYPE html>
<html>
...
</html> (目前主流)
2. HTML、XML、XHTML 之间有什么区别?
所以 HTML5 是HTML的新一代标准, 所谓的 H5 工程师这一词, 其实是国产词, 泛指新一代的web开发工程师,具体H5工程师, 做什么工作方向, 还是要看需求 (比如: 移动端开发, PC端网页开发, H5小游戏开发…)
3. Html5 新增那些标签?
语义化布局标签:
header,nav,main,article、section,aside,footer
表单标签: datalist
input:type=’week|date|time|datetime|number|search|url|tel|color|email|range’
多媒体标签: audio,video
其他标签: progress(进度条),meter
4. 行内元素和块级元素的区别?
- 行内元素会在一条直线上排列,块级元素独占一行。
- 行内元素设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效(margin和padding水平有效)
display:block (设为块级元素) ; display:inline (设为行内元素)
5. 列举几个块级标签和行内标签?
块级标签:div、p、h1~h6、section、header、footer
行内标签:a、span、em(i)、strong(b)、u
6. 行内元素的 padding 和 margin 可设置吗?
水平方向有效。
垂直方向没有对周围元素产生任何影响,因此无效。
7. 简述 readyonly 与 disabled 的区别
- readyonly 是设置表单元素为只读状态(不可编辑,可复制),只针对input(text/password)和textarea有效。
- disabled 是设置表单元素为禁用状态(不可编辑,不可复制),所有的表单元素有效。
注意:表单元素在使用了disabled后,当我们将表单以POST或GET的方式提交的话,这个元素的值不会被传递出去,而readonly会将该值传递出去
8. 前端做本地数据存储的方式以及区别?
9. 说说对 html 语义化的理解
HTML5 提供了新的语义元素来定义网页的不同部分,它们被称为“切片元素”,如图所示 :
- header:用于定义页面的头部区域,通常包括网站 logo、主导航、全站链接以及搜索框。
- nav:定义页面的导航链接部分区域。
- main:定义文档的主要内容,该内容在文档中应当是独一无二的。
- article:定义页面独立的内容,它可以有自己的 header、footer、sections等,专注于单个主题的博客文章,报纸文章或网页文章。
- section:表示文档中的一个区域(或节),比如,内容中的一个专题组。
- aside:表示一个和其余页面内容几乎无关的部分,被认为是独立于该内容的一部分且可以被单独的拆分出来而不会影响整体。通常表现为侧边栏或嵌入内容。
- footer:定义最近一个章节内容或者根节点元素的页脚。一个页脚通常包含该章节作者、版权数据或者与文档相关的链接等信息。
优点:
- 代码结构:使页面没有css的情况下,也能够呈现出很好的内容结构
- 有利于 SEO: 爬虫依赖标签来确定关键字的权重,因此可以和搜索引擎建立良好的沟通,帮助爬虫抓取更多的有效信息
- 提升用户体验:例如 title、alt 可以用于解释名称或者解释图片信息,以及 label 标签的灵活运用。
- 便于团队开发和维护:语义化使得代码更具有可读性,让其他开发人员更加理解你的 html 结构,减少差异化。
- 方便其他设备解析:如屏幕阅读器、盲人阅读器、移动设备等,以有意义的方式来渲染网页。
二、CSS3
1.px、em、rem、%、vw、vh单位之间的区别?
- px:像素,相对长度单位,相对于屏幕分辨率
- em:相对单位。默认的基准点为父元素的字体大小,而如果自身定义了字体大小则按自身的来算。所以即使在同一个页面内,1em可能不是一个固定的值。
- 相对单位。可以理解为 root em ,即基准点为根元素 < html > 的字体大小。rem是CSS3中新增单位,一般用于做移动端适配
- %:相对长度单位,指占用的父元素宽度/高度的比例。
- 1vh 等于1/100的视口高度,1vw 等于1/100的视口宽度。
html {
font-size: 25px;
}
那么1rem=25px;
移动端适配
rem布局的原理:
- 使用 rem 为单位
- 动态的设置 html font-size (媒体查询, js设置, 插件设置都可以)
webpack有工具, 可以写 px, 自动转 rem
2. 谈谈 css 选择器优先级顺序以及判定标准
!important > 行内样式 > ID选择器 > 类选择器 > 标签选择器 > 通配符选择器
如果两个选择器同时命中一个元素, 并且权重一样,后一个选择器的属性会覆盖前一个选择器中相同的属性
3. position 几个属性的作用?
- static :是 position 的默认属性值。
- relative:相对定位,偏移的 top,right,bottom,left 的值都以它原来的位置为基准偏移。 移动后的元素在原来的位置仍占据空间。
- absolute:绝对定位,如果父容器设置了 position 属性,就会依据父容器进行偏移。如果父容器没有设置 position 属性,那么偏移是以 body 为依据。设置 absolute 属性的元素在标准流中不占位置
- fixed:固定定位,元素的位置在屏幕滚动时不会改变,始终以 body 为依据。设置 fixed 属性的元素在标准流中不占位置。
子绝(absolute)父相(relative):
父盒子使用相对定位:页面上是占用位置的;子盒子以父盒子左上角为基准点进行移动,不会对下面的同级盒子产生影响。
应用:把脱离文档流的元素放在不脱离文档流(需要占位置)的元素上。
例如:将右侧的HOT移到中间。
4. 介绍一下盒模型?
标准盒模型(W3C)
总宽度 = 内容的width + padding(左右) + border(左右) + margin(左右)
IE盒模型
//设置为IE盒模型
box-sizing:border-box
总宽度 = 内容的width + margin(左右)
这里的width包含了padding(左右)和border(左右)的值
5. CSS实现上三角?
//设置border-bottom有颜色,其他透明。
.triangle{
width: 0px;
height:0px;
border-top: 100px solid transparent;
border-left: 100px solid transparent;
border-bottom: 100px solid blue;
border-right: 100px solid transparent;
}
6.谈谈对伪类和伪元素的理解
- 伪类是对已有元素的修饰
- 伪元素是在已有元素的基础上增加一个元素
- 大部分容器标签(大部分双标签)都有伪元素, iframe 没有伪元素。
大部分单标签都没有伪元素。 - Js不能操作伪元素
伪元素选择符:
伪类选择符:
7. 让元素水平居中的方法有哪些?
方法一:定位+margin:auto
子绝父相:在开发中,父级要占有位置,子级要随意摆放
块级元素设置居中的前提是设置了width,若在css中没写width则会默认占据100%的宽度,auto指平分剩余空间 。
<body>
<div class="father">
<div class="child"></div>
</div>
</body>
<style>
.father {
width: 200px;
height: 200px;
background-color: skyblue;
position: relative;
}
.child {
width: 100px;
height: 100px;
background-color: pink;
position: absolute;
//在知道父容器宽高的情况下margin:auto会平分剩余空间
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
</style>
方式二: 利用定位+transform
<body>
<div class="father">
<div class="child"></div>
</div>
</body>
<style>
.father {
width: 200px;
height: 200px;
background-color: skyblue;
position: relative;
}
.child {
width: 100px;
height: 100px;
background-color: pink;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
</style>
方式三:使用flex布局
<body>
<div class="father">
<div class="child"></div>
</div>
</body>
<style>
.father {
width: 200px;
height: 200px;
background-color: skyblue;
display: flex;
justify-content: center;
align-items: center;
}
.child {
width: 100px;
height: 100px;
background-color: pink;
}
</style>
8. 谈谈你对 flex 的理解?
容器的属性
- flex-direction:设置主轴方向
- flex-warp:设置换行方式
- flex-flow:上面两个属性的简写形式
- justify-content:定义项目在主轴的对齐方式
- align-items:定义项目在交叉轴的对齐方式
- align-content:定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
项目的属性
- order:定义项目的排列顺序。数值越小,排列越靠前,默认为0。
- flex-grow:定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
- flex-shrink:定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
- flex-basis:定义了在分配多余空间之前,项目占据的主轴空间
- flex:上面三个属性的简写,默认值为0 1 auto
- align-self:该属性允许单个项目有与其他项目不一样的对齐方式
注意:flex:1相当于flex: 1 1 auto。(撑满平分)。
9. 说说图片懒加载的原理?实际开发中用过哪些图片懒加载的插件?
原理:在图片没有进入可视区域时,先不给的src赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给src赋值。
实现懒加载的步骤:
- 加载loading图片
- 判断哪些图片要加载
- 隐形加载图片
- 替换真图片
vue 中图片懒加载的插件: vue-lazyload,,此外vue 的组件库中也有图片懒加载的组件。
10. CSS3新增特性
媒体查询(@media);
transfrom 系列:translate 平移,scale 缩放,rotate 旋转
动画(animate);
过渡效果(transition);
flex 弹性布局;
盒模型计算方式 box-sizing:border-box;
线性渐变(linear-gradient),径向渐变、伪元素
文字阴影(text-shadow),边框阴影(box-shadow),圆角(border-radius)
11. Less是什么?
Less 是一种 css 预处理语言, 在 less 中可以定义一些变量和表达式
以及使用嵌套语法。
less 中使用@定义变量(@baseColor:pink) 后期可以通过一些编译工具(less)将 less 编译成浏览器能直接识别的css 样式.,所以 less 只是在开发阶段使用的一种中间语言。
使用less 的目的是提高开发效率以及提高代码的可维护性
12.BFC是什么?
首先BFC是一个名词,是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子里面物品的摆放是不受外界的影响的。转换为BFC的理解则是∶BFC中的元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
三、JavaScript
1. js 中有哪些数据类型
基本数据类型:String、Number、boolean、null、undefined、symbol。(存放在栈中,值传递)
引用数据类型:object。(存放在堆中,传递的是地址)
2. typeof和 instanceof 的区别?
typeof
操作符返回一个字符串,表示未经计算的操作数的类型。
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'
instanceof
运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,返回值为布尔。
3. 怎么判断两个对象相等?
- 先判断俩者是不是对象;
- 再判断俩个对象的所有 key 值是否相等相同;
- 最后判断俩个对象的相应的 key 对应的值是否相同
4. js 中函数有哪些定义方式
//函数声明
function fn(){}
//函数表达式
var fn = function(){}
//构造函数
var fn = new Function(‘参数 1’,’参数 2’,’函数体’)
5. js 中函数有哪些调用形式?
- 普通函数
- 对象的方法
- 事件处理函数
- 构造函数
- 回调函数
6. Js操作数组的常用方法
1. Array.push(),向数组的末尾添加一个或多个元素,并返回新的数组长度。原数组改变。
2. Array.pop(),删除并返回数组的最后一个元素,若该数组为空,则返回undefined。原数组改变。
3. Array.unshift(),向数组的开头添加一个或多个元素,并返回新的数组长度。原数组改变。
4. Array.shift(),删除数组的第一项,并返回第一个元素的值。若该数组为空,则返回undefined。原数组改变。
5. Array.concat(arr1,arr2…),合并两个或多个数组,生成一个新的数组。原数组不变。
6. Array.join(),将数组的每一项用指定字符连接形成一个字符串。默认连接字符为 “,” 逗号。
7. Array.reverse(),将数组倒序。原数组改变
8. Array.sort(),对数组元素进行排序。按照字符串UniCode码排序,原数组改变。
①从小到大
7.数组遍历的方式有哪些?
四、JavaScript高级
1. 谈一下作用域和作用域链?
作用域:就是某个变量或函数有作用的范围
作用域链:函数内部可以访问到函数外部作用域的变量, 而外部函数还可以访问到全局作用域的变量,这样的变量作用域访问的链式结构, 被称之为作用域链。
2. 谈一下原型和原型链?
原型:每一个javascript对象(除null外)创建的时候,都会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型中“继承”属性。
- 所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
- 所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
- 所有引用类型的__proto__属性指向它构造函数的prototype
var a = [1,2,3];
a.__proto__ === Array.prototype; // true
原型链:每一个实例对象上有一个proto属性,指向的构造函数的原型对象,构造函数的原型对象也是一个对象,也有proto属性,这样一层一层往上找的过程就形成了原型链。
2. 什么是构造函数
在 JavaScript 中,用 new 关键字来调用的函数,称为构造函数。构造函数首字母一般大写。
3. 闭包是什么
闭包:指有权访问另一个函数作用域中变量的函数。
内层函数, 引用外层函数上的变量, 就可以形成闭包
闭包是一个跟函数相关的概念,表现形式是一个父函数内部,嵌套了一个子函数, 子函数直接或间接的被返回给外部作用域,,并且子函数中会使用到父函数局部作用域中的变量,当我们在外部调用这个子函数的时候,就会发生闭包现象.。
闭包的作用:闭包可以延展一个函数的作用域,使得外层函数也可以访问里层函数变量
注意事项:不能滥用闭包,会导致内存泄漏。
4. 说说你对 this 关键字的理解
- 普通函数中的this,永远指向window对象
- 对象方法中的this,指向调用该方法的对象
- 事件中的this,指向绑定该事件的元素
- 构造函数中的this,指向new调用时得到的函数对象
- 箭头函数没有自己的this,因此在箭头函数实际访问的是父级的this。
5. new操作符干了什么?
- 在内存中创建一个新的空对象。
- 让 this指向这个新的对象。
- 执行构造函数里面的代码,给这个新对象添加属性和方法。
- 返回这个新对象(所以构造函数里面不需要return ) 。
6. 谈谈深拷贝与浅拷贝
B复制A,A变,B变,浅拷贝。(复制并且共用一个引用)
B复制A,A变,B不变,深拷贝。(不同引用)
- 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址。(…拓展运算符)
- 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象。
//浅拷贝:
...拓展运算符
//深拷贝案例:
//JSON.stringify()把js对象转换为json字符串
//JSON.parse()把json字符串转换为js对象
JSON.parse(JSON.stringify(list))
7. 针对页面性能优化,你有哪些优化方案?
- 资源加载方面:
1.减少 http 请求次数,具体方案:代码合并(合并 css,js),使用精灵图。
2.减少 http 请求数据量,代码压缩(css,js,html),合理设置缓存。
3.启用 CDN 加速服务。
- 代码层面:
1.避免滥用全局变量, 减少作用域查找(能用局部变量就不要声明全局变量),不要滥用闭包。
2.减少 DOM 操作,操作 DOM 的时候对已经查找到的 DOM 对象进行缓存, 避免重复查找。
3.使用图片懒加载,避免单次加载图片数量过多导致页面卡顿。
4.将 script 标签写在页面底部,,因为 js 的加载会阻塞页面的渲染。
5.不要在本地书写大量 cookie,因为 cookie 会伴随每一次 http 请求。
8. 什么是 SEO
SEO 是一种通过优化网站内容和结构,提高网站在搜索引擎中的排名,从而增加网站流量和曝光度的技术和策略。
优化手段
- 合理的 title(标题)、description(描述)、keywords(关键词)
- 语义化的 HTML 代码,符合 W3C 规范
- 重要内容 HTML 代码放在最前
- 放良好的友情链接和高质量的外链
9. 谈谈Js中的垃圾回收机制
- 标记清除(mark and sweep)
是当变量进入环境(函数中声明变量)时,将这个变量标记为“进入环境”。当变量离开环境(函数执行结束)时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。
- 引用计数(reference counting):
这种方式常常会引起内存泄漏,低版本的 IE 使用这种方式。机制就是跟踪一个值的引用次数,当声明一个变量并将一个引用类型赋值给该变量时该值引用次数加 1,当这个变量指向其他一个时该值的引用次数便减一。当该值引用次数为 0时,就会被垃圾回收器释放内存。
10. 防抖与节流是什么?
- 防抖就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
- 节流就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率
防抖和节流都是用来控制某个函数在一定时间内触发次数,两者都是为了减少触发频率,以便提高性能或者说避免资源浪费。
防抖:就是回城,被打断就要重新来
节流:就是平A,短时间内点击无数次也只攻击一次
防抖:只触发最后一次。(节约性能)
应用场景:输入框输入时。例如快速敲击键盘123,没有防抖就会打印1,2,3每个数字,做了防抖则只会打印123
实现思路:
1.事件函数执行,先创建一个定时器
2.把逻辑代码放到定时器中
3.当函数再次触发,清除定时器
4.再创建一个新定时器
节流:间隔时间,延迟触发。(节约性能)
应用场景:1.鼠标不断点击,单位时间只触发一次;2.滚动条的下拉监听
11.一个页面从输入 URL 到页面加载显示完成,这个过程中都 发生了什么?
1.DNS域名解析,获取访问的IP地址
2.TCP连接:三次握手
3.(发送HTTP请求)
4.服务器处理请求并返回HTTP报文
5.浏览器解析渲染页面
6.连接结束:四次挥手
- 当发送一个 URL 请求时,浏览器会开启一个线程来处理这个请求,同时在远程 DNS 服务器上启动一个 DNS 查询,用来获得请求对应的 IP 地址。
- 浏览器与远程 Web 服务器通过 TCP 三次握手来建立一个TCP/IP 连接。该握手包括一个同步报文,一个同步—应答报文和一个应答报文,这三个报文在浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,然后服务器响应并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。
- 一旦 TCP/IP 连接建立,浏览器会通过该连接向远程服务器发送HTTP 的 GET 请求。远程服务器找到资源并使用 HTTP 响应返回该资源
- 此时,Web 服务器提供资源服务,客户端开始下载资源
五、ES6
1. ES6 新增了那些特性
- const(声明常量), let(声明变量)关键字;
- map 和 set 数据类型;
- 模板字符串;
- 对象数组解构赋值;
- 函数剩余参数;(…arg)
- 扩展运算符;(…)
- 函数默认参数;fn(name=’zs’)
- 对象字面量的增强(属性名和属性值相同, 可缺省);
- Promise 异步对象;
- class 类的支持
2. 使用 let和 var 声明的变量有什么区别
使用 let 声明的变量有块级作用域,,并且没有变量的声明提升( 使用
let 声明的变量在声明之前调用会报语法错误)。
使用 var 声明的变量有声明提升(在声明之前调用会报 undefined),没有块级作用域。
3. 对promise的理解
- Promise 是一种解决异步编程的方案,相比回调函数和事件更合理和更
强大。从语法上讲,promise 是一个对象,从它可以获取异步操作的消息 - promise 有三种状态:pending(等待状态),fulfiled(成功状态),rejected(失败状态);状态一旦改变,就不会再变。创造 promise实例后,它会立即执行。
- Promise 的两个特点
1、Promise 对象的状态不受外界影响
2、Promise 的状态一旦改变,就不会再变,任何时候都可以得到这个结
果,状态不可以逆, - Promise 的三个缺点
1、无法取消 Promise,一旦新建它就会立即执行,无法中途取消
2、如果不设置回调函数,Promise 内部抛出的错误,不会反映到外部
3、当处于 pending(等待)状态时,无法得知目前进展到哪一个阶段,
是刚刚开始还是即将完成 - 代码层面 Promise 提供了一个构造函数,在使用的时候必须通过new
创建一个实例对象,在创建实对象的时候需要传递一个匿名函数,这个匿名函数需要两个参数(resolve,reject),resolve成功处理函数,reject 失败处理函数。什么时候触发成功处理函数和失败处理函数,由具体的业务逻辑来决定。 - resolve 和 reject 需要通过 Promise 实例对象提供的 then 方法来传递。
- Promise 提供了两个静态方法 all和race。all 可以一次执行多个Promise实例。返回值是数组。race也可以一次执行多个Promise 实例, 哪个实例最先执行完, 就返回哪个的执行结果。
六、Vue
1. 说说你对MVVM的理解
- View 是视图层,也就是用户界面。前端主要由 HTML 和 CSS 来构建 。
- Model 是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,对于前端来说就是后端提供的 api 接口。
- ViewModel 是由前端开发人员组织生成和维护的视图数据层。在这一层前端开发者对从后端获取的 Model 数据进行转换处理,做二次封装,以生成符合 View 层使用预期的视图数据模型。需要注意的是 ViewModel 所封装出来的数据模型包括视图的状态和行为两部分,而 Model 层的数据模型是只包含状态的,比如页面的这一块展示什么,而页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互),视图状态和行为都封装在了 ViewModel 里。这样的封装使得 ViewModel 可以完整地去描述 View 层。
MVVM 框架实现了双向绑定,这样 ViewModel 的内容会实时展现在 View 层,前端开发者再也不必低效又麻烦地通过操纵 DOM去更新视图,MVVM 框架已经把最脏最累的一块做好了,我们开发者只需要处理和维护 ViewModel,更新数据视图就会自动得到相应更新。这样View 层展现的不是 Model 层的数据,而是 ViewModel 的数据,由 ViewModel 负责与 Model层交互,这就完全解耦了 View 层和 Model 层,这个解耦是至关重要的,它是前后端分离方案实施的重要一环。
2. Vue2.x响应式数据/双向绑定原理
Vue 数据双向绑定主要是指:数据变化更新视图,视图变化更新数据
其中,View变化更新Data,可以通过事件监听的方式来实现,所以 Vue数据双向绑定的工作主要是如何根据Data变化更新View。
简述:Vue2 是使用数据劫持, 结合发布者订阅者模式实现双向数据绑定的,利用Object.defineproperty()
方法将各个属性的getter
和setter
方法改写。当数据发生改变的时候,通知订阅者,并触发对应的回调函数,重新渲染数据。主要是实现以下几点:。
- 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用
Object.defineProperty
把这些 property 全部转为 getter/setter。 - 这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property被访问和修改时通知变更。
- 每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
3. 你知道Vue3的数据响应式原理吗?
Vue3.x改用Proxy替代Object.defineProperty。
Proxy 的优势如下:
- Proxy 可以直接监听对象而非属性
- Proxy 可以直接监听数组的变化
4. v-model双向绑定原理?
本质是v-bind
和v-on
的语法糖
- v-bind绑定一个value属性
- v-on指令给当前元素绑定input事件
5. Vuex是什么,什么情况下用?
Vuex是官方提供的Vue 应用的状态机。状态机就是用来管理应用程序中的数据。
主要包括以下几个模块:
- State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
- Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter映射到局部计算属性。
- Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
- Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
- Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。
如果应用够简单,最好不要使用 Vuex,一个简单的 store 模式即可,需要构建一个中大型单页应用时,使用Vuex能更好地在组件外部管理状态。
6. Vuex和单纯的全局对象有什么区别?
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit)mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
7. 说一下v-if和v-show的区别?
v-show:条件隐藏。浏览器先渲染HTML元素,符合条件就显示,不符合条display就为none,不显示,但是元素还在那。
v-if:条件渲染。浏览器先判断符不符合条件,符合了再渲染,否则不渲染DOM,浏览器中找不到这个DOM。
8. 为什么 v-for 和 v-if 不建议用在一起?
当 v-for 和 v-if 处于同一个节点时,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。如果要遍历的数组很大,而真正要展示的数据很少时,这将造成很大的性能浪费。
9. 组件中的data为什么是函数?
如果data是一个对象则会造成数据共享,在多次使用该组件时,改变其中一个组件的值会影响全部该组件的值。
如果是通过函数的形式返回出一个对象的话,在每次使用该组件时返回出的对象的地址指向都是不一样的,这样就能让各个组件的数据独立。
10. watch、computed 和 methods 的区别?
- methods 方法表示一个具体的操作,主要书写业务逻辑
- computed 属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用,不支持异步操作
- watch 不支持缓存,只要监听的数据变化就会触发相应操作;可以看作是 computed 和 methods 的结合体,支持异步操作
11. Vue 路由模块中 $route 和 $router 的区别?
- router 是 VueRouter 的一个对象,通过 Vue.use(VueRouter)和
VueRouter 构造函数得到一个 router 的实例对象,这个对象中是一个全
局的对象,他包含了所有的路由包含了许多关键的对象和属性 - route 是一个跳转的路由对象,每一个路由都会有一个 route 对象,是
一个局部的对象,可以获取对应的 name,path,params,query 等
12.如何实现跨域?
- JSONP
- CORS
- 服务器代理(webpack代理, Nginx反向代理)
13.vue组件之间如何进行通信?
- props(父传子)
- 自定义事件(子传父)
- eventBus(事件总线)
- $ children和$ parent
- ref 和 $refs 配合
- vuex
14.Vue-router 中hash模式和history模式的区别?
- 开发中默认使用hash模式,hash模式url里面永远带着#号。
- 如果用户考虑url的规范,就需要使用history模式,因为history模式没有#号适合推广宣传。
- 在开发时,分享页面到第三方app,有些app里面的url是不允许带有#号的,将#号去除就需要使用history模式。
- history模式的问题:在访问二级页面的时候,做刷新操作,会出现404错误,那么就需要和后端人员配合,让他配置一下apache或是nginx的url重定向,重定向到你的首页路由上就ok啦。
15.v-for循环为什么一定要绑定key?
- 页面上的标签都对应具体的虚拟dom对象(虚拟dom就是js对象)。
- 循环中 ,如果没有唯一key,页面上删除一条标签,由于并不知道删除的是哪一条,所以要把全部虚拟dom重新渲染。
- 如果知道key为x标签被删除掉,只需要把渲染的dom为x的标签去掉即可。