前端面试题

优化

加载优化

请说出三种减少页面加载时间的方法

(加载时间指感知的时间或者实际加载时间)

· 1.优化图片

· 2.图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方)

· 3.优化CSS(压缩合并css,如margin-top,margin-left…)

· 4.网址后加斜杠(如www.campr.com/目录,会判断这个“目录是什么文件类型,或者是目录。)

· 5.标明高度和宽度(如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。当浏览器知道了高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容。从而加载时间快了,浏览体验也更好了。)

· 6.减少http请求(合并文件,合并图片)。

HTMl

盒子模型

图片描述

clientWidth

属性表示元素的内部宽度,以像素计。该属性包括内边距,但不包括垂直滚动条(如果有)、边框和外边距。

如上图所示, 计算方式为, 分为如下两种:

  • 存在垂直滚动条

    content width + padding - scollbarWidth

  • 不存在滚动条

    content width + padding

clientHeight

属性表示元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距。

如上图所示, 计算方式为如下两种:

  • 存在水平滚动条

    content height + padding - scollbarWidth

  • 不存在滚动条

    content height + padding

clientLeft

表示一个元素的左边框的宽度.

计算方式为如下两种情况:

  • 如果文字方向从右往左(默认从左往右,通过设置 direction: rtl;)进行排列,且存在垂直滚动条的情况下

    border width + scollbar width

  • 默认情况下

    border width

注意:

如果当前元素是行内元素(inline)时, clientLeft将返回 0;

计算滚动条宽度

1
2
3
4
5
6
7
8
9
// 默认情况下(没有滚动条情况下) 
clientWidth = content width + paddingLeftWidth + paddingRightWidth;
// 对上面示例来说 clientWidth = 200 + 10 + 10;

// 有滚动条情况下:
clientWidth = (content width + paddingLeftWidth + paddingRightWidth) - scrollbarWidth

// 可以推断出滚动条计算方式:
scrollbarWidth = (content width + paddingLeftWidth + paddingRightWidth) - clientWidth;

两种盒子

介绍一下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的?

  • 有两种, IE盒子模型、W3C盒子模型;
  • 盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border);
  • 区 别: IE的content部分把 borderpadding计算了进去;

HTML5

html5有哪些新特性、移除了那些元素?

  • HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加
    • 绘画 canvas
    • 用于媒介回放的 videoaudio 元素
    • 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失
    • sessionStorage 的数据在浏览器关闭后自动删除
    • 语意化更好的内容元素,比如articlefooterheadernavsection
    • 表单控件,calendardatetimeemailurlsearch
    • 新的技术webworker, websocket, Geolocation
  • 移除的元素:
    • 纯表现的元素:basefontbigcenterfont, sstrike,tt,u`
    • 对可用性产生负面影响的元素:frameframesetnoframes
  • 支持HTML5新标签:
    • IE8/IE7/IE6支持通过document.createElement方法产生的标签
    • 可以利用这一特性让这些浏览器支持HTML5新标签
    • 浏览器支持新标签后,还需要添加标签默认的样式
  • 当然也可以直接使用成熟的框架、比如html5shim

CSS

选择器

CSS 中有四种不同的组合器:

  • 所有后代选择器 (空格)
  • 子选择器 (>)
  • 后面相邻兄弟选择器 (+)
  • 后面兄弟选择器 (~)

内联>ID选择器>伪类=属性选择器=类选择器>元素选择器【p】>通用选择器(*)>继承的样式

ID选择器「如:#header」,

Class选择器「如:.foo」,

属性选择器「如:[class]」,

伪类「如::link」,

标签选择器「如:h1」,

伪元素「如::after」,

选择器「*」

同级的后面覆盖前面的

列举不同的清除浮动的技巧,并指出它们各自适用的使用场景。

  1. 使用空标签清除浮动。这种方法是在所有浮动标签后面添加一个空标签定义css clear:both.弊端就是增加了无意义标签。

  2. 使用overflow。给包含浮动元素的父标签添加css属性overflow:auto;zoom:1;zoom:1用于兼容IE6。

  3. 使用after伪对象清除浮动。该方法只适用于非IE浏览器。具体写法可参照以下示例。使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置height:0,否则该元素会比实际高出若干像素;二、content属性是必须的,但其值可以为空,content属性的值设为”.”,空亦是可以的。

4.浮动外部元素

此三种方法各有利弊,使用时应择优选择,比较之下第二种方法更为可取。

如何优化网页的打印样式?

1
<link rel = "stylesheet" type = "text/css" media = "screen" href = "xxx.css"/>

其中media指定的属性就是设备,显示器上就是screen,打印机则是print,电视是tv,投影仪是projection。打印样式示例如下:

1
<link rel = "stylesheet" type = "text/css" media = "print" href = "yyy.css"/>

但打印样式表也应注意以下事项:

  • 打印样式表中最好不要用背景图片,因为打印机不能打印CSS中的背景。如要显示图片,请使用html插入到页面中。

  • 最好不要使用像素作为单位,因为打印样式表要打印出来的会是实物,所以建议使用pt和cm。

  • 隐藏掉不必要的内容。(@print div{display:none;})

  • 打印样式表中最好少用浮动属性,因为它们会消失。如果想要知道打印样式表的效果如何,直接在浏览器上选择打印预览就可以了。

解释一下你对盒模型的理解,以及如何在CSS中告诉浏览器使用不同的盒模型来渲染你的布局。

关于盒模型请看文章CSS之布局与定位

  • 请解释一下*{box-sizing:border-box;}的作用,并且说明使用它有什么好处?

说到IE的bug,在IE6以前的版本中,IE对盒模型的解析出现一些问题,跟其它浏览器不同,将border与padding都包含在width之内。而另外一些浏览器则与它相反,是不包括border和padding的。

在我们开发的过程中会发现,有时候,如果对页面中的大区域进行设置时,将border、padding计算到width和height之内,反而更灵活。但W3C的CSS2.1规范却规定了他们并不能被包含其中。考虑到这个问题,css3中引入了一个新的属性:box-sizing,它具有“content-box”和”border-box“两个值。

  • box-sizing:content-box

当我们设置box-sizing:content-box;时,浏览器对盒模型的解释遵从我们之前认识到的W3C标准,当它定义width和height时,它的宽度不包括border和padding。

  • box-sizing:border-box

当我们设置box-sizing:border-box;时,浏览器对盒模型的解释与IE6之前的版本相同,当它定义width和height时,border和padding则是被包含在宽高之内的。内容的宽和高可以通过定义的“width”和“height”减去相应方向的“padding”和“border”的宽度得到。内容的宽和高必须保证不能为负,必要时将自动增大该元素border box的尺寸以使其内容的宽或高最小为0

::before 和 :after中双冒号和单冒号 有什么区别?解释一下这2个的作用

  • 单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪元素
  • 用于区分伪类和伪元素

JS

class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Human {
constructor(name) {
this.name = name
this.kingdom = 'animal'
this.color = ['yellow', 'white', 'brown', 'black']
}
// 补全代码
getName () {
return this.name
}
}

// 补全代码
class Chinese extends Human{
constructor(name,a){
super(name)
this.a = a
}
getAge() {
return this.a
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Human(name) {
this.name = name
this.kingdom = 'animal'
this.color = ['yellow', 'white', 'brown', 'black']
}

function Chinese(name,age) {
Human.call(this,name)
this.age = age
this.color = 'yellow'
}

// 补全代码
Chinese.prototype = new Human();
Chinese.prototype.constructor = Chinese;
Human.prototype.getName = function() {
return this.name;
}
Chinese.prototype.getAge = function() {
return this.age;
}

typeof

img

prototype__proto__

prototype 是对该函数以及其实例函数的公用说明, 可以理解为, 在实例化的时候, js 会一并把该函数的的 prototype 一并付给实例化的对象
__proto__, 代表的是关于其父级的联系

1
2
3
4
function Person(){
}
let person = new Person();
person.__proto___=== Person.prototype // true

函数的 prototype !== __proto__

1
2
3
function Person(){}
Person.prototype ===Person.__proto__ // 不相等返回false
Person.prototype.__proto___===Person.__proto__.___proto___ // ture

重点解释下为什么第二条是 true, 首先万物皆对象, 所以 Person.prototype 是一个 object 而 Person.proto_也是一个的对象

所以 第二条也就是相等于:

1
2
Person.prototype.__proto___===Person.__proto__.___proto___
object.__proto___=== object.___proto___// 所以肯定是 true

相当于是 Object.prototype

解释下JavaScript中this是如何工作的。

this永远指向函数运行时所在的对象,而不是函数被创建时所在的对象。匿名函数或不处于任何对象中的函数指向window 。

1.如果是call,apply,with,指定的this是谁,就是谁。

2.普通的函数调用,函数被谁调用,this就是谁。

你是如何测试JavaScript代码的?

结合自己的项目经验进行讲述。(chrome使用技巧

AMD vs.CommonJS

请看文章JavaScript之模块化编程

描述以下变量的区别:null,undefined?

JavaScript的最初版本是这样区分的:null是一个表示”无”的对象,转为数值时为0;undefined是一个表示”无”的原始值,转为数值时为NaN。

但是,上面这样的区分,在实践中很快就被证明不可行。目前,null和undefined基本是同义的,只有一些细微的差别。

null表示”没有对象”,即该处不应该有值。典型用法是:

  • 用来初始化一个变量,这个变量可能被赋值为一个对象。
  • 用来和一个已经初始化的变量比较,这个变量可以是也可以不是一个对象。
  • 当函数的参数期望是对象时,被用作参数传入。
  • 当函数的返回值期望是对象时,被用作返回值传出。
  • 作为对象原型链的终点。

undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:

  • 变量被声明了,但没有赋值时,就等于undefined。
  • 调用函数时,应该提供的参数没有提供,该参数等于undefined。
  • 对象没有赋值的属性,该属性的值为undefined。
  • 函数没有返回值时,默认返回undefined。

该如何检测它们?

null:表示无值;undefined:表示一个未声明的变量,或已声明但没有赋值的变量,或一个并不存在的对象属性。

==运算符将两者看作相等。如果要区分两者,要使用===或typeof运算符。

以下是不正确的用法:

1
2
3
4
5
var exp = undefined;

if (exp == undefined) {
alert("undefined");
}

exp为null时,也会得到与undefined相同的结果,虽然null和undefined不一样。注意:要同时判断undefined和null时可使用本法。

typeof返回的是字符串,有六种可能:”number”、”string”、”boolean”、”object”、”function”、”undefined”。

以下是正确的用法:

1
2
3
4
5
var exp = undefined;

if(typeof(exp) == undefined) {
alert("undefined");
}

JS中如何判断null?

以下是不正确的用法:

1
2
3
4
5
var exp = null;

if(exp == null) {
alert("is null");
}

exp为undefined时,也会得到与null相同的结果,虽然null和undefined不一样。注意:要同时判断null和undefined时可使用本法。

1
2
3
4
5
var exp=null;

if(!exp) {
alert("is null");
}

如果exp为undefined或者数字零,也会得到与null相同的结果,虽然null和二者不一样。注意:要同时判断null、undefined和数字零时可使用本法。

1
2
3
4
5
var exp = null;

if(typeof(exp) == "null") {
alert("is null");
}

为了向下兼容,exp为null时,typeof总返回object。这种方式也不太好。

以下是正确的用法:

1
2
3
4
5
var exp = null;

if(!exp&&typeof(exp) != "undefined" && exp != 0) {
alert("is null");
}

什么是闭包,如何使用它,为什么要使用它?

包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。

所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

使用闭包的注意点:

  • 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

  • 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

(关于闭包,详细了解请看JavaScript之作用域与闭包详解

你使用过JavaScript模板系统吗?

如有使用过,请谈谈你都使用过哪些库,比如laytpl,Mustache.js,Handlebars等等。

防抖和节流

函数防抖(debounce)

解释:当持续触发某事件时,一定时间间隔内没有再触发事件时,事件处理函数才会执行一次,如果设定的时间间隔到来之前,又一次触发了事件,就重新开始延时。

1
2
3
4
5
6
7
8
9
10
11
function debounce(fn, wait) {
let timeout = null
return function() {
if(timeout !== null) clearTimeout(timeout)
timeout = setTimeout(fn, wait);
}
}
function handle() {
console.log(Math.random())
}
window.addEventListener('scroll', debounce(handle, 1000))

函数节流(throttle)

解释:当持续触发事件时,有规律的每隔一个时间间隔执行一次事件处理函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function throttle(fn, delay) { 
var prev = Date.now()
return function() {
var now = Date.now()
if (now - prev > delay) {
fn()
prev = Date.now()
}
}
}
function handle() {
console.log(Math.random())
}
window.addEventListener('scroll', throttle(handle, 1000))

作用域

题1

考察点

作用域、this、声明提升

示例

1
2
3
4
5
6
7
8
9
var a = 10;
function test(){
a = 100;
console.info(a);
console.info(this.a);
var a;
console.info(a);
}
test();

结果

100
10
100

其中

var a;会被提到方法的开始执行相当于

1
2
3
4
5
6
7
8
9
10
var a = 10;
function test(){
var a = undefinded;
a = 100;
console.info(a);
console.info(this.a);

console.info(a);
}
test();

如果是 let 就不会声明提升

var 的三个问题

  1. 声明提升
  2. 没有块级作用域
  3. 变量覆盖

题2

考察点

自执行、作用域、预解析

示例

1
2
3
4
5
6
(function(){
var b = a = 3;
})();

console.info(a);
console.info(b);

结果

3
Uncaught ReferenceError: b is not defined

源代码相当于

1
2
3
4
5
6
7
(function(){
a = 3;
var b = a;
})();

console.info(a);
console.info(b);

题3

考察点

事件循环、等待队列、异步、单线程

示例

1
2
3
4
5
for(var i = 1;i<=3;i++){
setTimeout(function(){
console.info(i);
},0);
}

结果

1
2
3
4
4
4

原因

所有的异步任务会被放在等待队列,等主线程运行完成后,在把异步任务放到主线程中运行。

循环的执行顺寻为

1
2
3
4
var i = 1;
i<+3;
方法体;
i++;

然后 2,3,4循环执行

如果是这样的

1
2
3
4
5
for(let i = 1;i<=3;i++){
setTimeout(function(){
console.info(i);
},0);
}

结果为

1
2
3
1
2
3

作用域

var 全局作用域函数作用域

es6中let 块级作用域

题4

考察点

作用域、声明提升、参数

示例

1
2
3
4
5
6
7
8
function test(n){
console.info(n);
var n = 456;
console.info(n);
}

var n = 123;
test(n);

结果

1
2
123
456

原代码就相当于

1
2
3
4
5
6
7
8
9
10
function test(n){
var n = undefinded;
n = n;
console.info(n);
n = 456;
console.info(n);
}

var n = 123;
test(n);

题5

如果

1
2
3
4
5
6
7
8
function test(){
console.info(n);
n = 456;
console.info(n);
}

var n = 123;
test(n);

结果

1
2
123
456

原因

内部未定义找不到就会去外部找;

题6

考察点

作用域

示例

1
2
3
4
5
6
7
8
9
10
11
12
var n = 123;
function f1(){
console.info(n);
}

function f2(){
var n = 456;
f1();
}

f2();
console.info(n);

结果

1
2
123
123

原因

调用函数 无调用者 调用者就是 window

题7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var length = 100;
function f1(){
console.info(this.length);
}

var obj = {
x:10,
f2:function(f1){
f1();
console.info(arguments);
arguments[0]();
}
}

obj.f2(f1,1);
console.info(obj.length);

结果

1
2
100
2

原因

第一个 f1(); 无调用者 调用者是window;

第二个 arguments[0]();也是无调用者,调用者是arguments

其中arguments其实是对象,但是有length属性

image-20220521103256268

Promise

1
2
3
4
5
6
7
8
9
10
11
let promise = new Promise((resove,reject)=>{
console.info(1);
resove();
console.info(2);
});

promise.then(()=>{
console.info(3);
});

console.info(4);

结果

1
2
3
4
1
2
4
3

原因

new Promise() 是 同步的 then是异步 先执行同步在执行异步

数组去重

1
2
3
let arr = [1,2,1,2,3]
let item = [...new Set(arr)];
console.info(item);

call、apply、bind

call、apply、bind 都是用来修改函数中的this,

传参时,call是一个个传参,apply是数组形式传参,call和apply立即执行并且返回值是你调用的方法的返回值,若该方法没有返回值,则返回undefined。

bind是改变this后返回一个新的函数,他不会立即执行。
这三个方法不会改变原方法的this的指向。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let a = {
name: "小明",
play: function(name1, name2) {
console.info(this.name + "和" + name1 + "、" + name2 + "一块玩");
}
};

let b = {
name: "小红"
};

a.play("小刚", "小李");


a.play.call(b, "小刚", "小李");
a.play.apply(b, ["小刚", "小李"]);
a.play.bind(b)("小刚", "小李");

深拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function deepClone(source){
let targetObj = source.constructor === Array ?[]:{};
for(let key in source){
let value = source[key];
if(value && typeof value === 'object'){
targetObj[key] == value.constructor === Array ?[]:{};
targetObj[key] = deepClone(value);
}else{
targetObj[key] = value;
}
}
return targetObj;
}

let o1 = {name:"123",age:18};
let o2 = deepClone(o1);
o2.age = 19;
console.info(o1);
console.info(o2);

Jquery

Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解

  • 使用.bind()方法非常浪费性能因为它把同一个事件处理函数附加到了每一个匹配的元素上
  • 你应该停止使用.live()方法因为它被弃用了同时也会带来很多问题 事件注册到document上
  • 使用.delegate()方法会给你带来很多好处当你需要解决一些性能上的问题和对动态添加的元素作出处理
  • 新的.on()方法其实就是模拟.bind().live().delegate()实现的语法糖,具体取决于你如何调用它
  • 新的方向是使用新的.on()方法。先熟悉语法,并开始在你的所有的Jquery 1.7版本以上的项目使用它吧!

在Jquery 1.7版本中.bind().live().delegate()方法只需要使用.on()方法一种方式来调用它们。

1
2
3
4
5
6
7
8
9
10
11
12
13
/* Jquery的 .bind() , .live() 和 .delegate() 方法只需要使用`.on()`方法一种方式来调用它们 */

// Bind
$( "#members li a" ).on( "click", function( e ) {} );
$( "#members li a" ).bind( "click", function( e ) {} );

// Live
$( document ).on("click", "#members li a", function( e ) {} );
$( "#members li a" ).live( "click", function( e ) {} );

// Delegate
$( "#members" ).on("click", "li a", function( e ) {} );
$( "#members" ).delegate( "li a", "click", function( e ) {} );

请指出$$.fn的区别。

Jquery为开发插件提供了两个方法,分别是:

1
2
$.extend(obj);
$.fn.extend(obj);
  • 1.那么这两个分别是什么意思?

$.extend(obj);是为了扩展jquery本身,为类添加新的方法。

$.fn.extend(obj);给JQUERY对象添加方法。

  • 2.$.fn中的fn是什么意思,其实是prototype,即​$.fn=$.prototype;

具体用法请看下面的例子:

1
2
3
4
5
6
7
8
$.extend({

add:function(a, b) {
return a+b;
}
})

$.add(5,8); // return 13

注意没有,这边的调用直接调用,前面不用任何对象。直接$.+方法名

$.fn.extend(obj);对prototype进行扩展,为jquery类添加成员函数,jquery类的实例可以使用这个成员函数。

1
2
3
4
5
6
7
8
9
10
$.fn.extend({
clickwhile:function(){

$(this).click(function(){
alert($(this).val())
})
}
})

$('input').clickwhile(); // 当点击输入框会弹出该对象的Value值

注意调用时候前面是有对象的。即$('input')这么个东西。

VUE

Vue的生命周期

  • beforeCreate(创建前) 在数据观测和初始化事件还未开始
  • created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
  • beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
  • mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
  • beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
  • updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
  • beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
  • destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

Vue组件间的参数传递

  1. 父组件与子组件传值
    父组件传给子组件:子组件通过props方法接受数据;
    子组件传给父组件:$emit方法传递参数

  2. 非父子组件间的数据传递,兄弟组件传值
    eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。)

Vuex是什么?怎么使用?哪种功能场景使用它?与cookie的区别?

只用来读取的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。

场景有:单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车.

state
Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。

mutations
mutations定义的方法动态修改Vuex 的 store 中的状态或数据。

getters
类似vue的计算属性,主要用来过滤一些数据。

action
actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。

计算属性和方法的区别

其他

  • 1.css只在当前组件起作用
    答:在style标签中写入scoped即可 例如:<style scoped></style>

  • 2.v-if 和 v-show 区别
    答:v-if按照条件是否渲染,v-show是display的block或none;

  • 3.$route$router的区别
    答:$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等。

  • 4.vue.js的两个核心是什么?
    答:数据驱动、组件系统

  • 5.vue几种常用的指令
    答:v-for 、 v-if 、v-bind、v-on、v-show、v-else

  • 6.vue常用的修饰符?
    答:.prevent: 提交事件不再重载页面;.stop: 阻止单击事件冒泡;.self: 当事件发生在该元素本身而不是子元素的时候会触发;.capture: 事件侦听,事件发生的时候会调用

  • 7.v-on 可以绑定多个方法吗?
    答:可以

  • 8.vue中 key 值的作用?
    答:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。

  • 9.什么是vue的计算属性?
    答:在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:①使得数据处理结构清晰;②依赖于数据,数据更新,处理结果自动更新;③计算属性内部this指向vm实例;④在template调用时,直接写计算属性名即可;⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。

  • 10.vue等单页面应用及其优缺点
    答:优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
    缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。