vue2面试题:公司真实vue2面试题整理

vue2面试题:公司真实vue2面试题整理编辑排版 宋大狮平台运营 小唐狮一 说一下 vue2 的生命周期 创建 beforecreate 实例创建前此阶段的 data methods computed watch 的数据和方法不能被访问 created 实例创建完成后此阶段完成数据

大家好,欢迎来到IT知识分享网。

vue2面试题:公司真实vue2面试题整理

编辑排版 | 宋大狮

平台运营 | 小唐狮

一、说一下vue2的生命周期?

创建:

beforecreate:

实例创建前

此阶段的data、methods、computed、watch的数据和方法不能被访问

created:

实例创建完成后

此阶段完成数据监听,可以使用数据、更改数据。无法与Dom进行交互,想要的话可以通过nextTick来访问。

挂载:

beforeMount:

页面渲染前

此阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated。

mounted:

页面渲染完成后

此阶段真实Dom渲染完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作。

更新:

beforeUpdate:

响应式数据更新前

此阶段更改数据,不会造成页面重新渲染。

updated:

响应式数据更新完成后

避免在此阶段更改数据,因为这可能会导致无限循环的更新。

销毁:

beforeDestroy:

实例销毁前

我们可以在这时进行善后收尾工作,比如清除定时器、解除绑定事件

destroyed:

实例销毁完成后

缓存:

activited:

keep-alive专属,组件被激活时调用

deactivited:

keep-alive专属,组件被销毁时调用

1、异步请求放在created还是mounted:

如果是单单的一个父级组件,放哪里都无所谓。

如果涉及到了要控制子父组件先后显示正确内容的时候,就可以考虑下父组件的请求要放在哪个钩子里了。想要子组件先拿到数据渲染就放在mounted中,想要父组件先拿到数据就放在created中。

2、第一次加载页面触发了创建、挂载生命周期

3、父子组件生命周期执行顺序:

组件渲染的顺序是先父后子,渲染完成的顺序是先子后父

组件更新的顺序是先父后子,更新完成的顺序是先子后父

组件销毁的顺序是先父后子,销毁完成的顺序是先子后父

二、说一下v-show、v-if、v-for的理解?

v-show和v-if的区别:

v-if:通过操控DOM增删来实现显示隐藏,不适合频繁切换,数据多不建议用v-if,每一次切换则重新消耗性能

v-show:修改元素的display实现显示隐藏,适合频繁切换,只在第一次渲染时消耗性能

v-if和v-for的优先级:

当v-if与v-for一起使用时,v-for比v-if优先级高,如果连用的话会把v-if给每个元素都添加一下,会造成性能问题,所以不推荐v-if和v-for在同一个标签中同时使用。

解决办法:在计算属性中,将v-if中的判断转化成对v-for数组的过滤

v-for中key的作用?

key代表的是唯一,作用是更高效的更新虚拟dom,diff算法时便于区分新旧虚拟dom,新旧虚拟dom的key相同时不会重新渲染,提高性能

为何不推荐index作为key值:当以数组下标index作为key值时,当其中一个元素发生了变化(增删改查),就有能导致所有的元素的key值发生改变,导致更新dom时浪费性能

三、说一下组件通信有哪些方式?

父传子

1、自定义属性 + props:在父组件中,给子组件绑定一个自定义属性,在子组件中,通过props进行接收

2、$parent:直接访问父组件实例的属性和方法

3、$attrs:在父组件中,给子组件绑定一个自定义属性,在子组件中,通过$attrs进行接收【与props不能共存】

4、插槽

子传父

1、$emit + 自定义事件:在父组件中,给子组件绑定一个自定义事件,绑定事件的值为接收参数的函数,在子组件中,通过$emit发送数据

2、$refs:直接访问子组件实例的属性和方法

3、$children:直接访问子组件实例的属性和方法【返回数组,必须遍历赋值后才能渲染】

祖传孙

1、provide函数传,inject数组收

2、自定义属性 + v-bind=”$attrs”【中间人】 + $attrs

孙传祖

1、$emit + v-on=”$listeners”【中间人】 + 自定义事件

兄弟间

1、$bus 全局事件总线:给vue原型添加一个vue实例,用this.$bus.$emit发送,用this.$bus.$on接收

2、Vuex

3、pubsub 发布订阅

路由传参

params传参(地址栏不显示参数)

query传参(地址栏显示参数)

四、watch和computed的区别

computed计算属性:

1、如果一个数据需要经过复杂计算就用computed

2、支持缓存,只有依赖数据发生改变时,才会重新进行计算

3、不支持异步,当计算属性内有异步操作时,无法监听到数据的变化。原因:定义的函数接收return的结果,return属于同步执行的,是没办法拿到异步请求结果的

4、计算属性只能取不能存,即不能对计算属性直接赋值。如需要存,要给计算属性手动添加setter

watch监听器:

1、如果一个数据需要被监听并且对数据做一些操作就用watch

2、不支持缓存,数据变化会直接触发相应的操作

3、支持异步

设置deep:true 开启深度监听,如果监听的是对象类型,当手动修改对象的某个属性时,可以被监听到

设置immediate:true watch初始化时会立即执行一次handler方法

五、说一下为什么data是一个函数?

data必须是函数,是为了保证不同组件的独立性和可复用性,防止不同组件实例间data的引用关系,避免变量污染

六、说一下什么是路由守卫?

是路由跳转前、后的一些钩子函数

分类:

全局守卫:【写在main.js中 或 router文件夹下的index.js中】

beforeEach: 进入路由之前的验证(常用,如:判断用户是否登录)

afterEach: 路由进入之后的验证(常用,如:修改页面标题)

局部守卫:【写在路由组件内单独的守卫】

beforeRouteEnter: 进入路由之前的验证

beforeRouteLeave: 离开路由之前的验证(常用,离开当前页面提示是否保存内容)

beforeRouteUpdate: 组件路由更新前的验证

独享守卫:【相当于写在路由配置里的全局守卫,只有前置守卫】

beforeEnter:进入路由之前的验证

三个参数:

to: 要进入的路由对象

from: 要离开的路由对象

next: 放行函数

七、说一下路由传参方式query和params的区别?

1、传参方式

query通过path进行跳转传参,接收的时候通过this.$route.query进行接收

params通过name进行跳转传参,接收的时候通过this.$route.params进行接收

2、安全性

params传值不会显示到地址栏,安全性高,但页面刷新数据会丢失

query传值会暴露在地址栏,页面刷新不会丢失

八、说一下路由模式hash和history的区别?

在单页面应用SPA中,路由描述的是URL与视图之间的映射关系,这种映射是单向的,即URL变化引起视图更新(无需刷新页面)。

1、hash模式

原理:

用 url + #后面的hash值 来模拟一个完整的url,直接刷新页面不会导致浏览器向服务器发出新的请求,路由切换时不会

当调用$router.push方法,会改变hash值触发hashchange事件,前进到指定的url。vue-router会根据url做路由匹配来修改页面内容,实现路由切换的效果

改变hash值触发hashchange事件,hashchange事件对象中会记录变化的url。点击浏览器的前进后退,会改变hash值,实现路由切换的效果

特点:

地址栏有#,影响美观,直接刷新页面不会报404

2、history模式

原理:

用 url + 路径 真正实现一个完整的url,直接刷新页面会导致浏览器向服务器发出新的请求,路由切换时不会

当调用$router.push方法,会改变路径调用pushState方法,前进到指定的url。vue-router会根据url做路由匹配来修改页面内容,实现路由切换的效果

改变路径调用pushState方法,pushState方法中会记录变化的url。点击浏览器的前进后退 或者 手动调back、forward、go方法,会触发popstate事件,实现路由切换的效果

特点:

地址栏没有#,不影响美观,直接刷新页面会报404,需要后端在Nginx中做代理地址的配置

九、说一下对keep-alive的理解?

缓存组件,减少请求次数

根据条件缓存页面的方式:

:include=”[‘组件name’]” 指定想要缓存的组件,其他组件不缓存

:exclude=”[‘组件name’]” 指定不想要缓存的组件,其他组件缓存

利用路由的元属性meta,配合v-if动态判断

两个钩子函数:

activated():进入这个缓存组件时触发

deactivated():离开这个缓存组件时触发

十、说一下对vuex的理解?

五种状态:

state: 存储公共数据 this.$store.state

mutations:同步操作,改变store的数据 this.$store.commit()

actions: 异步操作,让mutations中的方法能在异步操作中起作用 this.$store.dispatch()

getters: 计算属性 this.$store.getters

modules: 子模块

使用场景:

用户信息、菜单信息、购物车信息

解决vuex页面刷新数据丢失问题的方式:

办法一:将vuex中的数据直接保存到浏览器缓存中(sessionStorage、localStorage、cookie)

办法二:在页面刷新的时候再次请求远程数据,使之动态更新vuex数据

办法三:在某一组件向后台请求远程数据保存在vuex,并且在页面刷新前将vuex的数据保存至sessionStorage。在另一组件优先使用vuex内的数据,只有刷新后还没取到后台数据,才会从sessionStorage里取。

优点:每次刷新页面更新sessionStorage,确保数据的安全性。刷新后还没取到后台数据就从sessionStorage中取,防止网络延迟、数据量大时vuex数据丢失问题。

十一、说一下对MVVM的理解?

M是model,指的是数据层,即data

V是view,指的是视图层,即template

VM是viewModel,指的是视图模型,即vue实例,是连接view和model的桥梁。数据和视图不能直接通信,必须经过VM实现通信。

十二、说一下vue2的响应式原理?

vue2采用数据代理+数据劫持+发布订阅模式的方法。

在初始化vue实例时,会把data对象和data对象的属性都添加到vm对象中,通过object.defineProperty()进行数据代理,用vm对象的属性来代理data对象的属性,

并在Observer类中递归遍历data对象,对data对象中的每个属性都进行数据劫持,都指定一个getter、setter。

例外的,对于数组,不能通过object.defineProperty()进行数据代理,因为监听的数组下标变化时会出现数据错乱问题,所以数组是调用数组重写的原生方法来实现响应式。

当通过vm对象修改data对象中的属性时,会触发data属性的setter方法,然后触发它Dep实例的notify方法进行依赖分发,通知所有依赖的Watcher实例执行内部回调函数。

最后会触发renderWatcher回调,会重新执行render函数,重新对比新旧虚拟DOM,重新渲染页面。

【Watcher回调是异步任务,它的执行会遵循事件循环机制,且重复的Watcher回调不会放到任务队列中,所以多次重复数据更新时,只会重新渲染一次页面】。

当通过vm对象读取data对象中的属性时,会触发data属性的getter方法,然后触发它Dep实例的depend方法进行依赖收集。

当data对象中数组元素发生变化时,会调用数组重写的原生方法,然后触发它Dep实例的notify方法进行依赖分发,通知所有依赖的Watcher实例执行内部回调函数。

最后会触发renderWatcher回调,会重新执行render函数,重新对比新旧虚拟DOM,重新渲染页面。

当读取data对象中数组元素时,会触发数组的getter方法,然后触发它Dep实例的depend方法进行依赖收集。

十三、说一下v-model数据双向绑定原理?

是一个语法糖,做了两件事

v-bind绑定value,更新数据层

v-on给元素绑定input事件,监听输入框中的内容,当发生改变时来执行一些事情,并更新视图层

十四、说一下$set的作用和原理?

作用:

对象:

响应式原理:通过触发setter实现更新

对象中后追加的属性、删除已有属性,Vue默认不做响应式处理

解决:this.$set()

数组:

响应式原理:调用重写的原生方法实现更新

数组中修改某下标的元素、更新length,Vue默认不做响应式处理

解决:

1. this.$set()

2. 使用原生API:push、pop、shift、unshift、splice、sort、reverse

原理:

如果目标是数组,直接使用数组的splice方法通知实现更新

如果目标是对象,先给对象属性用数据代理添加getter、setter,再通过触发setter通知实现更新

十五、说一下虚拟DOM的原理?

虚拟dom是对真实dom的抽象,本质是JS对象

在生成真实DOM之前,vue会把模板编译为一个虚拟dom,当里面某个DOM节点发生变动时,通过diff算法对比新旧虚拟DOM,发现不一样的地方直接修改在真实的DOM上

优点:

可以减少DOM操作

可以跨平台渲染

缺点:

严重依赖打包工具

节点规模过大时,虚拟DOM的稳定性不如原生DOM

十六、说一下vue的模板编译过程?

1、获取到template

2、template 转 AST树

AST树:

抽象语法树(一个对象的格式)

源代码的抽象语法结构的树状描述

用于将vue的指令、语法等 转为 源代码的抽象语法结构

3、AST树 转 render函数

render函数:

返回包含_c、_v、_s函数的字符串

4、执行render函数 转 虚拟DOM

5、执行patch方法,通过diff算法对比新旧虚拟DOM,打补丁,生成真实DOM

十七、说一下单页面应用和多页面应用的区别?

单页面应用(SPA):

项目只有一个html页面,只向服务器请求一次静态资源,所有页面跳转都是通过路由组件切换完成的

优点:页面跳转快、组件化开发

缺点:首屏加载慢、不利于SEO

多页面应用(MPA):

项目有多个html页面,每次页面跳转都要向服务器请求静态资源,返回新的html页面

优点:首屏加载快、利于SEO

缺点:页面跳转慢

十八、说一下CSS预处理器Less和Sass的区别?

Sass和Less都属于CSS预处理器,都需要编译器编译成css文件运行

一般常用的功能是:变量、运算符、混合、嵌套层级

区别:

1、编译环境不一样

Sass基于Ruby环境

Less基于JS环境

2、变量符不一样

Less是@,而Sass是$

3、功能性不一样

Sass功能性强大,有函数、条件判断、循环遍历、数据结构的概念

Less没有

十九、说一下对跨域的理解?

http请求分为两大类:普通http请求(如百度请求)和ajax请求(跨域是出现在ajax请求)

同源策略:在浏览器发起ajax请求时,当前的网址和被请求的网址协议、域名、端口号必须完全一致,目的是为了防止跨站脚本攻击。

跨域是浏览器的同源策略导致的,而服务器之间不受同源策略影响!!!

前端本地开发存在跨域,但前端部署到服务器上就不存在跨域了!!!

解决方式:

1、CORS跨域资源共享

在配置类中,添加一个CORS的过滤器,在响应头上添加允许访问的请求源 addAllowedOrigin(“*”)

2、Jsonp

利用srcipt标签的src属性来实现,前端声明好一个函数,后端返回执行函数,执行函数参数中携带所需的数据。

可以使用jquery的ajax快速实现Jsonp。

使用jsonp只能解决get请求的跨域,因为script标签中的src请求就是get请求。

3、vue脚手架正向代理

跨域解决:vue脚手架自动在本地开启一个基于node的代理服务器,IP和端口号与本地浏览器相同

浏览器【http://localhost:8080】 -> 本地代理服务器【http://localhost:8080】 -> 目标服务器【http://47.94.222.12:8080】

4、Nginx反向代理

跨域解决:location配置中,在响应头上添加允许访问的请求源 Access-Control-Allow-Origin:*

浏览器【http://localhost:8080】 – Nginx代理服务器【添加放行请求源】 – 目标服务器【http://192.168.0.120:8080】

二十、说一下nextTick的使用场景和原理?

等待DOM更新后,再执行内部传入的回调函数

使用场景:

created中想要获取DOM

响应式数据变化后获取DOM更新后的状态,如 获取列表更新后的高度

原理:

把nextTick回调方法放在renderWatcher回调之后执行,这样就能拿到更新后的DOM

二十一、说一下对单向数据流的理解?

概念:父级给子组件是啥,子组件可以用,也可以不用,但是不能修改【单向数据流针对于组件通信】

作用:保证了数据的可控性,方便预测和调试

注意:Vue中的单向数据流是针对基本数据类型,而引用类型是对数据地址的引入,子组件修改数据,父组件能接收到数据的更改

应用:

父子传参:子组件不能直接修改父组件的数据,要么通过props从父组件传递过来,要么通过emit在父组件中修改

vuex:改变store中的状态state的唯一途径就是显式地提交mutation,不能直接修改state

– END –

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/89391.html

(0)
上一篇 2026-04-05 11:45
下一篇 2026-04-05 14:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信