写在前面:2020年面试必备的Java后端进阶面试题总结了一份复习指南在Github上,内容详细,图文并茂,有需要学习的朋友可以Star一下!
GitHub地址:https://github.com/abel-max/Java-Study-Note/tree/master
1.MVVM和MVC的区别?
MVC:MVC模式可以这样理解,将html看成view;js看成controller,处理用户与应用的交互,响应对view的操作(对事件的监听),调用Model对数据进行操作,完成model与view的同步(根据model的改变,通过选择器对view进行操作);将js的ajax当做Model,从服务器获取数据,MVC是单向的。
MVVM:它实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用再自己手动操作Dom元素,来改变View的显示,而是改变属性后该属性对应View层显示会自动改变,MVVM是双向的。
2.写一个简单的函数判断类型?
Object.prototype.toString.call()进行判断(输出结果在F12试试去吧)
3.实现简单的数组求和?
eval([1,2,3].join("+"))或者arr.reduce();
4.实现简单的数组去重?
基础数据结构数组:
[...new Set([...])]或Array.from(new Set(array))(set返回的结构不是数组类型)
对象数组类型数组:
方法一:
//定义常量 res,值为一个Map对象实例
const res = new Map();
//返回arr数组过滤后的结果,结果为一个数组
//过滤条件是,如果res中没有某个键,就设置这个键的值为1
return arr.filter((a) => !res.has(a) && res.set(a, 1))
方法二:
// 方法2:利用reduce方法遍历数组,reduce第一个参数是遍历需要执行的函数,第二个 参数是item的初始值33
var obj = {};
arr = arr.reduce(function(item, next) {
obj[next.key] ? '' : obj[next.key] = true && item.push(next);
return item;
}, []);
5.请写出你所知道的元素水平垂直居中?最少两种,三种良好,四种优秀
①绝对定位水平垂直居中
<div style="position: absolute;
width: 500px;
height: 300px;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: green;">水平垂直居中</div>
② 水平垂直居中
<div style="position: relative;
width:400px;
height:200px;
top: 50%;
left: 50%;
margin: -100px 0 0 -200px;
background-color: red;">水平垂直居中</div>
③ 水平垂直居中
<div style="position: absolute;
width:300px;
height:200px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: blue;">水平垂直居中</div>
④ flex 布局居中
<div style="display: flex;align-items: center;justify-content: center;">
<div style="width: 100px;height: 100px;background-color: gray;">flex 布局</div>
</div>
6.Map和Set的区别?
Set 对象类似于数组,且成员的值都是唯一的。
Map 对象是键值对集合,和 JSON 对象类似,但是 key 不仅可以是字符串还可以是对象
7.跨域是什么原因引起?怎么解决?
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。
① jsonp函数
在HTML DOM中, script标签本身就可以访问其它域的资源,不受浏览器同源策略的限制,可以通过在页面动态创建script标签。
var script = document.createElement('script');
script.src = "http://aa.xx.com/js/*.js";
document.body.appendChild(script);
② iframe实现跨域
基于iframe实现的跨域要求两个域具有aa.xx.com,bb.xx.com这种特点,也就是两个页面必须属于同一个顶级基础域(例如都是xxx.com,或是xxx.com.cn),使用同一协议(例如都是 http)和同一端口(例如都是80),这样在两个页面中同时添加document.domain,就可以实现父页面调用子页面的函数
③ 跨 域资源共享(CORS)
服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
④ 使用HTML5的window.postMessage方法跨域
window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
⑤nginx反向代理
8.谈一谈 CSS重绘与回流/重排 ?
会触发重绘或回流/重排的操作
①添加、删除元素(回流+重绘)
②隐藏元素,display:none(回流+重绘),visibility:hidden(只重绘,不回流)
③移动元素,如改变top、left或移动元素到另外1个父元素中(重绘+回流)
④改变浏览器大小(回流+重绘)
⑤改变浏览器的字体大小(回流+重绘)
⑥改变元素的padding、border、margin(回流+重绘)
⑦改变浏览器的字体颜色(只重绘,不回流)
⑧改变元素的背景颜色(只重绘,不回流)
9.let,var和const有什么区别?
const定义的变量不可以修改,而且必须初始化
var定义的变量可以修改,如果不初始化会输出undefined,不会报错。
let是块级作用域,函数内部使用let定义后,对函数外部无影响。
10.箭头函数和普通函数有什么区别?
主要区别在this指向问题
①普通函数的this 指向调用它的那个对象,例如 obj.func ,那么func中的this就是obj
②箭头函数不能作为构造函数,不能使用new,没有this,arguments箭头函数,箭头函数的this永远指向其上下文的 this ,任何方法都改变不了其指向,如 call() , bind() , apply()(或者说箭头函数中的this指向的是定义时的this,而不是执行时的this)
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
console.log(this.name); // My Object
return function(){
return this.name; // The Window
};
},
b: () => {
return this.name; // the window
},
c: function() {
return () => {
return this.name; //My Object
}
}
}
11.谈谈你对闭包的理解?
函数声明的时候,会生成一个独立的作用域,同一作用域的对象可以互相访问,作用域呈层级包含状态,形成作用域链,子作用域的对象可以访问父作用域的对象,反之不能;另外子作用域会使用最近的父作用域的对象
12.谈谈原型链继承的理解?
什么是原型链:只要是对象就有原型, 并且原型也是对象, 因此只要定义了一个对象, 那么就可以找到他的原型, 如此反复, 就可以构成一个对象的序列, 这个结构就被称为 原型链所有的实例有一个内部指针 (prototype) ,指向它的原型对象,并且可以访问原型对象上的所有属性和方法。
13.求数组交集?并集?
① 直接使用 filter、concat 来计算
var a = [1,2,3,4,5]
var b = [2,4,6,8,10]
//交集
var c = a.filter(function(v){ return b.indexOf(v) > -1 })
//差集
var d = a.filter(function(v){ return b.indexOf(v) == -1 })
//补集
var e = a.filter(function(v){ return !(b.indexOf(v) > -1) })
.concat(b.filter(function(v){ return !(a.indexOf(v) > -1)}))
//并集
var f = a.concat(b.filter(function(v){ return !(a.indexOf(v) > -1)}));
console.log("数组a:", a);
console.log("数组b:", b);
console.log("a与b的交集:", c);
console.log("a与b的差集:", d);
console.log("a与b的补集:", e);
console.log("a与b的并集:", f);
② 借助扩展运算符(...)以及 Set 的特性实现相关计算,代码也会更加简单些
var a = [1,2,3,4,5]
var b = [2,4,6,8,10]
console.log("数组a:", a);
console.log("数组b:", b);
var sa = new Set(a);
var sb = new Set(b);
// 交集
let intersect = a.filter(x => sb.has(x));
// 差集
let minus = a.filter(x => !sb.has(x));
// 补集
let complement = [...a.filter(x => !sb.has(x)), ...b.filter(x => !sa.has(x))];
// 并集
let unionSet = Array.from(new Set([...a, ...b]));
console.log("a与b的交集:", intersect);
console.log("a与b的差集:", minus);
console.log("a与b的补集:", complement);
console.log("a与b的并集:", unionSet);
14.谈谈localStorage,sessionStorage和cookies的区别?
① sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储
② localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的
③ cookie 数据始终在同源的http请求中携带,即cookie在浏览器和服务器之间来回传递
15.介绍一下重绘和回流?需要怎么优化?
①用transform 代替 top,left ,margin-top, margin-left... 这些位移属性
② opacity 加上 transform: translateZ/3d 这个属性之后便不会发生回流和重绘了
③不要使用 js 代码对dom 元素设置多条样式,选择用一个 className 代替之。
④如果确实需要用 js 对 dom 设置多条样式那么可以将这个dom 先隐藏,然后再对其设置
⑤不要使用table 布局,因为table 的每一个行甚至每一个单元格的样式更新都会导致整个table 重新布局
⑥对于频繁变化的元素应该为其加一个 transform 属性,对于视频使用video 标签
16.谈一谈vue的虚拟DOM是什么回事?
Vue.js通过编译将模版转换成渲染函数(render),执行渲染函数就可以得到一个虚拟DOM
简单点讲,在Vue的实现上,Vue讲模版编译成虚拟DOM渲染函数。结合Vue自带的响应系统,在状态改变时,Vue能够智能地计算出重新渲染组件的最小代价并应用到DOM操作上。
17.http常见的状态?
200("OK")
一切正常。实体主体中的文档(若存在的话)是某资源的表示。
400("Bad Request") 客户端方面的问题。实体主题中的文档(若存在的话)是一个错误消息。希望客户端能够理解此错误消息,并改正问题。
500("Internal Server Error") 服务期方面的问题。实体主体中的文档(如果存在的话)是一个错误消息。该错误消息通常无济于事,因为客户端无法修复服务器方面的问题。
301("Moved Permanently") 当客户端触发的动作引起了资源 URI 的变化时发送此响应代码。另外,当客户端向一个资源的旧 URI 发送请求时,也发送此响应代码。
404("Not Found") 和 410("Gone") 当客户端所请求的 URI 不对应于任何资源时,发送此响应代码。
404 用于服务器端不知道客户端要请求哪个资源的情况;
410 用于服务器端知道客户端所请求的资源曾经存在,但现在已经不存在了的情况。
409("Conflict") 当客户端试图执行一个 ” 会导致一个或多个资源处于不一致状态 “ 的操作时,发送此响应代码。
18.谈谈用户从输入url到页面渲染完成发生了什么过程?
①浏览器的地址栏输入URL并按下回车。
②浏览器查找当前URL的DNS缓存记录。
③DNS解析URL对应的IP。
④根据IP建立TCP连接(三次握手)。
⑤HTTP发起请求。
⑥服务器处理请求,浏览器接收HTTP响应。
⑦渲染页面,构建DOM树。
⑧关闭TCP连接(四次挥手)。
19.谈谈深拷贝和浅拷贝?
浅拷贝 :浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间,当内存销毁的时候,指向这片内存的几个指针需要重新定义才可以使用,要不然会成为野指针。
深拷贝: 深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后,两个对象虽然存的值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉。
20.css有哪些选择器?权重?
选择器类型:
1、ID#id
2、class.class
3、标签p
4、通用*
5、属性[type="text"]
6、伪类:hover
7、伪元素::first-line
8、子选择器、相邻选择器
权重计算规则:
1、第一等:代表内联样式,如: style=””,权值为1000。
2、第二等:代表ID选择器,如:#content,权值为0100。
3、第三等:代表类,伪类和属性选择器,如.content,权值为0010。
4、第四等:代表类型选择器和伪元素选择器,如div p,权值为0001。
5、通配符、子选择器、相邻选择器等的。如*、>、+,权值为0000。
6、继承的样式没有权值。
21.说说flex布局? Flex (Flexible Box),也就是”弹性布局”,它可以很灵活地实现垂直居中、多列布局等自适应问题。而任何一个容器都可以指定为 Flex 布局。设为 Flex 布局以后,子元素的 float 、 clear 和 vertical-align 属性将失效。
22.介绍一下盒模型?
① 盒模型:内容 (content) 、填充 (padding) 、边界 (margin) 、 边框 (border)
② 类型: IE 盒子模型、标准 W3C 盒子模型;
③ 两种盒模型的主要区别是 : 标准盒模型的宽高是值内容宽高 (content)
④ 而 IE 盒模型的宽高是指 content+padding+border 。
⑤ 设置盒模型的方式是:设置 box-sizing box-sizing:content-box 标准盒模型, box-sizing:border-box IE 盒模型
23.解释一下变量提升?
在进入一个执行上下文后,先把 var 和 function 声明的变量前置,再去顺序执行代码。
PS :作用域分为全局作用域和函数作用域,用 var 声明的变量,只在自己所在的所用域有效。
我们举例来看看下面的代码。
示例一
console.log(fn); var fn = 1; function fn() { } console.log(fn);
相当于
var fn = undefined; function fn() { } console.log(fn); fn = 1; console.log(fn);
示例二
console.log(i); for (var i = 0; i < 3; i++) { console.log(i) }
相当于
var i = undefined; console.log(i); for (i = 0; i < 3; i++) { console.log(i); }
24.如何理解事件委托?
也可以称之为事件代理,给父元素绑定事件,用来监听子元素的冒泡事件,并找到是哪个子元素的事件。将事件委托给另外的元素,利用事件冒泡的特性,将里层的事件委托给外层事件,将事件绑定到目标元素的父节点,根据event对象的属性进行事件委托,改善性能。事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件委托</title>
</head>
<body>
<ul id="list">
<li>我是第一个li</li>
<li>我是第二个li</li>
<li>我是第三个li</li>
<li>我是第四个li</li>
<li>我是第五个li</li>
</ul>
</body>
<script>
window.onload = function(){
var list = document.getElementById("list");
var li = document.getElementsByTagName("li");
list.onmouseover = function(env){
// 兼容获取event对象
var env = env || window.event;
// 兼容获取目标对象 env.target为标准 env.srcElement为IE
var target = env.target || env.srcElement;
// 判断目标对象是否是li
// target.nodeName 可以获取节点名称,通过toLowerCase()可以将节点名称的大小转换为小写
if(target.nodeName.toLowerCase()=== "li"){
target.style.background = "red";
}
}
}
</script>
</html>
25.介绍一下webpack基本的属性?
const path = require('path')
module.exports = {
entry: { // main是默认入口,也可以是多入口
main: './src/main.js'
},
// 出口
output: {
filename: './build.js', // 指定js路径
path: path.join(__dirname, '..', '', 'dist') // 最好是绝对路径
// 代表上一级的dist
},
module: {
// 一样的功能rules: webpack2.xx新加的
loaders: [ // require('./a.css||./a.js')
{
test: /\.css$/,
loader: 'style-loader!css=loader',
//多个loader用!分割
//顺序是反过来的 2!1 多个loader
},
{
test: /\.(jpg|svg)$/,
loaderL 'url-loader?limit=4096&name=[name].[ext]',
// limit=4096&name=[name].[ext]' 多个参数之间用&符号分割
//[name].[ext]内置提供的
options: {
limit: 4096,
name: '[name].[ext]'
}
}
]
},
plugins: [
// 插件的执行顺序是依次执行的,和loader是反过来的
new htmlWebpackPlugin({
template: './src/index.html',
})
// 将src下的template属性描述的文件根据当前配置的output.path,将文件移动到该目录。
// 在插件的执行过程中,它本身可以去拿当前所设置的webpack选项,便于对webpack选项的复用,
]
}
26.vue的双向数据绑定原理?
实现mvvm的双向绑定,是采用数据劫持结合 发布者-订阅者模式 的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
27.vue组件通信?
① 父组件向子组件传值 -- Props传递数据
在父组件中使用儿子组件
<template>
<div>
父组件:{{money}}
<Son1 :money="money"><Son1>
</div>
</template>
<script>
import Son1 from ''./Son1";
export default{
components:{
Son1
},
data(){
return { money: 100};
}
};
</script>
子组件接受数据
props:{
value:{
type:Number,
default:1
}
}
如果是数组
props:{
value:{
type:Array,
default: ()=>[]
}
}
②子组件通信父组件 $emit使用
子组件触发父组件方法,通过回调的方式将修改的内容传递给父组件
父组件
<template>
<div>
父组件:{{money}}
<Son1 :money="money" @input="change"><Son1>
</div>
</template>
<script>
import Son1 from ''./Son1";
export default{
methods:{
change(data){
this.money = data
}
},
components:{
Son1
},
data(){
return { money: 100};
}
};
</script>
子组件触发绑定自己身上的方法
<template>
<div>
子组件1:{{money}}
<button @click="$emit('input',200)">修改父组件的值<Son1>
</div>
</template>
<script>
export default{
props:{
money:{
type:Number
}
}
};
</script>
③ children(多层级传递)
<Grandson1 :value="value"></Grandson1>
<template>
<div>
孙子1:{{value}}
<---调用父组件的input事件-->
<button @click="$parent.$emit('input',200)">更改<Son1>
</div>
</template>
<script>
export default{
props:{
value:{
type:Number
}
}
};
</script>
④listeners:
$attrs批量向下传入属性
<Son2 name="小明" age="18"></Son2>
<--可以在son2组件中使用$attrs,可以将属性继续向下传递-->
<div>
儿子2:{{ $attrs.name }}
<Grandson2 v-bind="$attrs"></Grandson2>
</div>
<tempalte>
<div>孙子:{{$attrs}}</div>
</template>
$listeners批量向下传入方法
<Son2 name="小明" age="18" @click=“()=>{this.money =500}”></Son2>
<--可以在son2组件中使用$attrs,可以将属性继续向下传递-->
<Grandson2 v-bind="$attrs" v-on="$listeners"></Grandson2>
<button @click="$listeners.click()">更改<Son1>
⑤Provide&Inject
Provide 在父级中注入数据
provide(){
return {parentMsg:'父亲'};
}
Inject
在任意子组件中可以注入父级数据
inject:['parentMsg']//会将数据挂载在当前实例上
⑥ref使用
获取组件实例
<Grandson2 name="花花" ref="grand2"></Grandson2>
mounted(){
console.log(this.$refs.grand2.name);
}
⑦EventBus: 用于跨组件通知
Vue.prototype.$bus = new Vue();
Son2组件和Grandson1互相通信
mounted() {
//父亲组件注册
this.$bus.$on('my',data=>{
console.log(data)
})
}
mounted(){
//侄子组件调用
this.$nextTick(()=>{
this.$bus.$emit('my',"我是小红”);
})
}
28.vue中method,computed和watch三者的区别?
computed-- 适用于重新计算比较费时不用重复数据计算的环境。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。如果一个数据依赖于其他数据,那么把这个数据设计为 computed
watch-- 像是一个 data 的数据监听回调,当依赖的 data 的数据变化,执行回调,在方法中会传入 newVal 和 oldVal 。可以提供输入值无效,提供中间值 特场景。 Vue 实例将会在实例化时调用 $watch() ,遍历 watch 对象的每一个属性。如果你需要在某个数据变化时做一些事情,使用 watch 。
method-- 跟前面的都不一样,我们通常在这里面写入方法,只要调用就会重新执行一次
29.vue-route是怎么实现的?
vue-router通过hash与History interface两种方式实现前端路由,更新视图但不重新请求页面”是前端路由原理的核心之一
hash模式: 在浏览器中符号“ # ”, # 以及 # 后面的字符称之为 hash ,用 window.location.hash 读取;特点:hash虽然在 URL 中,但不被包括在 HTTP 请求中;用来指导浏览器动作,对服务端安全无用, hash 不会重加载页面。
history模式 :history采用 HTML5 的新特性;且提供了两个新方法:pushState(), replaceState ()可以对浏览器历史记录栈进行修改,以及 popState 事件的监听到状态变更。
30.vue中$nexTrick有什么用?
在Vue生命周期的 created() 钩子函数进行的DOM操作一定要放在 Vue.nextTick() 的回调函数中。原因是什么呢,原因是在 created() 钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进 Vue.nextTick() 的回调函数中
31.vue中$set有什么用?
在我们使用vue进行开发的过程中,可能会遇到一种情况:当生成vue实例后,当再次给数据赋值时,有时候并不会自动更新到视图上去,因此可以使用$set。
initTableData() {
this.tableData.forEach(element => {
this.$set(element, 'edit', false)
})
}
32.vue生命周期的理解?
Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 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 (销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
33.v-if和v-show的区别?
v-if是通过控制dom节点的存在与否来控制元素的显隐;v-show是通过设置DOM元素的display样式,block为显示,none为隐藏;
基于以上区别,因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
34.router的区别?
$router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。
$route对象表示当前的路由信息,包含了当前 URL 解析得到的信息
**1.$route.path** 字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"。
**2.$route.params** 一个 key/value 对象,包含了 动态片段 和 全匹配片段, 如果没有路由参数,就是一个空对象。
**3.$route.query** 一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 $route.query.user == 1, 如果没有查询参数,则是个空对象。
**4.$route.hash** 当前路由的 hash 值 (不带 #) ,如果没有 hash 值,则为空字符串。锚点
**5.$route.fullPath** 完成解析后的 URL,包含查询参数和 hash 的完整路径。
**6.$route.matched** 数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
**7.$route.name 当前路径名字**
**8.$route.meta 路由元信息
35.vue组件data为什么必须是函数?
如果data是一个函数的话,这样每复用一次组件,就会返回一份新的 data ,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份 data ,就会造成一个变了全都会变的结果。
36.vue中怎么自定义指令?
① 定义全局的自定义变量
main.js
Vue.directive('color',{
inserted(el){
// 各单位注意,这里的el获取的是标签元素,说白了就是可以直接操作DOM console.log(el)
el.style.color = "red"
}
})
<div >前端伪大叔</div>
<div v-color>前端伪大叔</div>
② 组件内指令-只有自己组件可以使用
// template
<div >前端伪大叔</div>
<div v-color>前端伪大叔</div>
// script
directives:{
color:{
inserted(el){
el.style.color = 'cyan'
}
}
}
37.对keep-aerlive的了解?
通过设置了keep-alive,可以简单理解为从页面1跳转到页面2后,然后后退到页面1,只会加载缓存中之前已经渲染好的页面1,而不会再次重新加载页面1,及不会再触发页面一种的created等类似的钩子函数,除非自己重新刷新该页面1。
38.vue中key的作用?、
强制替换元素,从而可以触发组件的生命周期钩子或者触发过渡。因为当 key 改变时,Vue认为一个新的元素产生了,从而会新插入一个元素来替换掉原有的元素。
<transition> <span :key="text">{{text}}</span> </transition>、
--这里如果text发生改变,整个<span>元素会发生更新,因为当text改变时,这个元素的key属性就发生了改变,在渲染更新时,Vue会认为这里新产生了一个元素,而老的元素由于key不存在了,所以会被删除,从而触发了过渡。
同理,key属性被用在组件上时,当key改变时会引起新组件的创建和原有组件的删除,此时组件的生命周期钩子就会被触发。
39.vue中常用的路由钩子函数有哪一些?
全局守卫:
router.beforeEach 全局前置守卫 进入路由之前
router.beforeResolve 全局解析守卫 (2.5.0+) 在 beforeRouteEnter 调用之后调用
router.afterEach 全局后置钩子 进入路由之后
路由组件内的守卫:
beforeRouteEnter 进入路由前
beforeRouteUpdate (2.2) 路由复用同一个组件时
beforeRouteLeave 离开当前路由时
40.谈谈前端性能优化?
①减少HTTP请求:合并文件、 CSS 精灵、 inline Image
②减少DNS查询: DNS 查询完成之前浏览器不能从这个主机下载任何任何文件。方法: DNS 缓存、将资源分布到恰当数量的主机名,平衡并行下载和 DNS 查询
③避免重定向:多余的中间访问
④使Ajax可缓存
⑤非必须组件延迟加载⑦未来所需组件预加载
⑥减少DOM元素数量
⑦将资源放到不同的域下:浏览器同时从一个域下载资源的数目有限,增加域可以提高并行下载量
⑧减少iframe数量
41.谈谈toString和String的区别?
toString() 方法;数值、字符串、对象、布尔;都有 toString 方法;这个方法唯一能做的就是返回相应的字符串;其中 null 和 undefined 没有 toString() 方法;
String() 属于强制转换, null 转换的结果为 null ; undefined 转换的结果为 undefined ;其余的如果有 toString() 方法,即调用该方法,返回相应的结果;
42.babel转换es6语法工作原理?
babel是一个转译器,感觉相对于编译器compiler,叫转译器transpiler更准确,因为它只是把同种语言的高版本规则翻译成低版本规则,而不像编译器那样,输出的是另一种更低级的语言代码。
但是和编译器类似,babel的转译过程也分为三个阶段: parsing、transforming、generating ,以ES6代码转译为ES5代码为例,babel转译的具体过程如下:
ES6代码输入 ==》 babylon进行解析 ==》 得到AST
==》 plugin用babel-traverse对AST树进行遍历转译 ==》 得到新的AST树
==》 用babel-generator通过AST树生成ES5代码
43.vue中常用的修饰符?
.stop //组织单击事件冒泡
.prevent //提交事件不再重新加载页面
.capture //添加事件侦听器时使用事件捕获模式
.self //只当事件在该元素本身时触发回调(在其子元素上不触发)
.once //只触发一次事件
44.vuex中的成员?对应的作用?
state => 基本数据
getters => 从基本数据派生的数据
mutations => 提交更改数据的方法,同步!
actions => 像一个装饰器,包裹mutations,使之可以异步。
modules => 模块化Vuex