2021 前端 VUE 面试题总汇

2021 前端 VUE 面试题总汇一 vue 面试题 1 vue 的生命周期 beforeCreate 实例初始化之后 数据观测和事件配置之前调用 组件的选项对象还没有创建 el 挂载和 data 都没有初始化 无法访问方法和数据 created 实例创建完成之后调用 已经完成了数据观测 属性方法的运算 watch event 事件回调 data 数据初始化已经完成 el 挂载还没有开始 beforeMount 挂载之前调用 el 初始化已经完成 vdom 已经完成 data 和模板的结合生成 html 但是还没有挂载到 html 页面里 mounted 挂载

文章目录

1、vue的生命周期

2、Vue2.x 双向绑定原理

vue 是通过 数据劫持 结合 发布者-订阅者 来实现双向绑定;数据劫持通过Object.defineProperty()方法的get和set方法来重新定义,set是设置属性值触发的函数,get是读取属性值触发的函数;

底层实现:

详细过程参考

3、Vue3.x 响应式原理

Vue3.x改用 Proxy 替代 Object.defineProperty。因为 Proxy 可以直接监听对象和数组的变化,并且有多达13种拦截方法。并且作为新标准将受到浏览器厂商重点持续的性能优化。

Proxy只会代理对象的第一层,那么Vue3又是怎样处理这个问题的呢?

判断当前Reflect.get的返回值是否为Object,如果是则再通过reactive方法做代理, 这样就实现了深度观测。

监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?

我们可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。

4、v-for 为什么要加上 key

function sameVnode (a, b) { return ( a.key === b.key && ( ( a.tag === b.tag && a.isComment === b.isComment && isDef(a.data) === isDef(b.data) && sameInputType(a, b) ) || ( isTrue(a.isAsyncPlaceholder) && a.asyncFactory === b.asyncFactory && isUndef(b.asyncFactory.error) ) ) ) } 

5、Vdom的理解

vdom 就是用 js 对象来描述真实 DOM,虚拟DOM的实现就是普通对象包含tag、data、children等属性对真实节点的描述。(本质上就是在JS和DOM之间的一个缓存);由于直接操作 DOM 性能低,但是 js 层的操作效率高,可以将 DOM 操作转化成对象操作,最终通过diff算法比对差异进行更新DOM (减少了对真实DOM的操作)。虚拟DOM不依赖真实平台环境从而也可以实现跨平台。

优点:

缺点:

无法进行极致优化: 在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化

6、vuex 的结构,以及 actiion 和 mutation 的区别

结构:state(初始化数据)、action(异步处理数据)、mutation(唯一能够修改state的操作)、getter(从state中动态获取相关数据)、module(模块化)

区别:

7、axios 的原理以及优点,如何终止 axios 请求

原理:属于 XMLHttpRequest,是一个基于 Promise 的 http 请求库,可用于浏览器和 Node

优点:

const CancelToken = axios.CancelToken; const source = CancelToken.source(); axios.get('/user/12345', { cancelToken: source.token }).catch(function(thrown) { if (axios.isCancel(thrown)) { console.log('Request canceled', thrown.message); }else { // 处理错误 } }); source.cancel('xxx'); 

2)、通过传递一个 executor 函数到CancelToken构造函数创建cancel token

const CancelToken = axios.CancelToken; let cancel axios.get('/user/12345', { cancelToken: new CancelToken(function executor(c){ cancel = c }) }); cancel(); 

注意: executor 处理器函数接收两个函数 resolve 和 reject 作为参数,异步任务执行成功调用 resolve,否则调用reject。

8、vue 的缺点

9、vue 和 react 区别

相同:

不同:

10、computed 和 watch 区别,以及 computed 如何实现缓存和更新的

区别

watch的参数:
deep:深度监听
immediate :组件加载立即触发回调函数执行




computed缓存原理:
conputed本质是一个惰性的观察者;当计算数据存在于 data 或者 props里时会被警告;

vue初次运行会对 computed 属性做初始化处理(initComputed),初始化的时候会对每一个 computed 属性用 watcher 包装起来 ,这里面会生成一个 dirty 属性值为 true;然后执行 defineComputed 函数来计算,计算之后会将 dirty 值变为 false,这里会根据 dirty 值来判断是否需要重新计算;如果属性依赖的数据发生变化,computed 的 watcher 会把 dirty 变为 true,这样就会重新计算 computed 属性的值。

11、hash 和 history 区别 ,分别是怎么实现的

区别:

原理:
hash:通过 onhashchange 事件监听 hash 变化,然后根据 hash 的变化更新页面部分内容(hash变化不会触发浏览器请求,但是会触发 hashchange 事件)。
history:主要是 H5 新增的两个 API(pushState、replaceState);他们可以改变url,但是不会发送请求,这样就可以通过 onpopstate 监听 url 变化来实现页面部分内容更新。




补充:pushState、replaceState 这两个方法应用于浏览器的历史记录栈,在当前已有的back、forward、go的基础上,他们提供了对当前浏览器进行修改的功能,只是当它们被修改时,虽然浏览器的URL发生

12、nextTick 作用和实现

作用:vue 更新 dom 是异步更新的,数据变化,dom 的更新不会马上完成;nextTick 的回调是在下次 DOM 更新循环结束之后执行的延迟回调。

13、solt 插槽种类以及原理

种类:
1)、匿名插槽:只能有一个
2)、实名插槽:可以有多个,在使用时必须使用name属性来标识




原理:

//子组件 <span> <slot v-bind:user="user"> { 
  { user.lastName }}  
     slot>  
      span> 

绑定在 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:

//父组件 <current-user> <template v-slot:default="slotProps"> { 
  { slotProps.user.firstName }}  
     template>  
      current-user> 

我们选择将包含所有插槽 prop 的对象命名为 slotProps,但你也可以使用任意你喜欢的名字。

原理:

本题参考

14、keep-alive使用和原理

缓存实现过程:

15、MVVM 和 MVC

1)、MVVM 即 Model-View-ViewModel 的简写。即模型-视图-视图模型。模型(Model)指的是后端传递的数据。视图(View)指的是所看到的页面。视图模型(ViewModel)是 mvvm 模式的核心,它是连接 view 和 model 的桥梁。它有两个方向:一是将模型(Model)转化成视图(View),即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。二是将视图(View)转化成模型(Model),即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。

2)、MVC 是 Model-View- Controller 的简写。即模型-视图-控制器。M 和 V 指的意思和 MVVM 中的 M 和 V 意思一样。C 即 Controller 指的是页面业务逻辑。使用 MVC 的目的就是将 M 和 V 的代码分离。MVC 是单向通信。也就是 View 跟 Model,必须通过 Controller 来承上启下。MVC和MVVM的区别并不是VM完全取代了C,只是在MVC的基础上增加了一层VM,只不过是弱化了C的概念,ViewModel 存在目的在于抽离 Controller 中展示的业务逻辑,而不是替代 Controller,其它视图操作业务等还是应该放在Controller中实现。也就是说MVVM实现的是业务逻辑组件的重用,使开发更高效,结构更清晰,增加代码的复用性。

可以参考阮一峰的文章很详细

16、template 模板引擎的渲染过程

template 的作用是模板占位符,可帮助我们包裹元素,但在循环过程当中,template不会被渲染到页面上

17、SPA页面的理解

SPA (single-page application:单页面应用程序)在页面初始化的时候加载相应的 HTML、js、css,一旦加载完成,页面不会因为用户的操作进行页面的重新加载或者跳转,而是使用路由机制实现HTML内容转换,避免页面重新加载。

优点:

缺点:

18、vue 性能优化?

npm install --save-dev compression-webpack-plugin@1.1.11 

在nginx.conf 里面配置

http { //在 http中配置如下代码, gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 8; #压缩级别 gzip_buffers 16 8k; #gzip_http_version 1.1; gzip_min_length 100; #不压缩临界值 gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; } 
 <body> <div id="app"> 
     div> <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"> 
      script> <script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"> 
       script> <script src="https://cdn.bootcss.com/vue-router/3.0.4/vue-router.min.js"> 
        script>  
         body> 

在 vue.config.js(vue-cli3) 文件 ,build/webpack.base.conf.js(vue-cli2)文件,增加 externals,将引入的外部模块导入

module.exports = { entry: { app: './src/main.js' }, externals:{ 'vue': 'Vue', 'vue-router': 'VueRouter', 'vuex':'Vuex' } 

最后、去掉 inport 以及 Vue.use(xxx)

//import Vue from 'vue' //import Router from 'vue-router' //import Vuex from 'vuex' //Vue.use(Router) ///Vue.use(Vuex) 

好处:加快打包速度,减轻服务器访问压力。

7)、代码精简,去除 console ,可复用的方法、组件提取出来

8)、不要写行内样式,避免dom重绘

10)、SPA页面采用keep-alive缓存组件

11)、key保证唯一性

12)、v-if 当值为false时内部指令不会执行,具有阻断功能,很多情况下使用v-if替代v-show

13、服务端渲染ssr

19、父子组件加载顺序

20、Vue.use是做什么的,原理是什么

21、Proxy 与 Object.defineProperty 优劣对比

22、v-model 的原理

v-model本质就是一个语法糖,可以看成是value + input方法的语法糖,是 vue 的双向绑定指令。一方面 model 层通过 defineProperty 来劫持每个属性,一旦监听到变化通过相关的页面元素更新。另一方面通过编译模板文件,为控件的 v-model 绑定 input 事件,从而页面输入能实时更新相关 data 属性值。

可以通过model属性的prop和event属性来进行自定义。原生的v-model,会根据标签的不同生成不同的事件和属性。

23、v-if 和 v-show 的区别

24、v-for 和 v-if 优先级

25、Vue.mixin 使用场景和原理

Vue.mixin的作用就是抽离公共的业务逻辑,原理类似“对象的继承”,在使用 mixin 的组件中引入后,mixin 中的方法和属性也就并入到该组件中,可以直接使用;当组件初始化时会调用 mergeOptions 方法进行合并,采用策略模式针对不同的属性进行合并,如果混入的数据和本身组件中的数据冲突,会采用“就近原则”以组件的数据为准。

//全局引用 main.js import mixin from './mixin' Vue.mixin(mixin) //在vue文件中引用 import '../mixin'; // 引入mixin文件 export default { mixins: [mixin] } 

同名选项合并:

26、Vue.set

起因:因为 ES5 的限制,vue 无法检测到对象属性的添加和删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

用法:Vue.set(target, key, value)

向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性。(对象不可以是 Vue 实例)

执行流程:

Vue.set( ) 是将 set 函数绑定在 Vue 构造函数上,this.$set() 是将 set 函数绑定在 Vue原型上。

27、组件中写 name 选项有哪些好处

28、vue 组件通讯有哪些方法

1)、props / $emit 适用 父子组件通信(常规操作)

父组件通过 props 传值给子组件,子组件 $emit 把自己的消息发送给父组件

2)、ref 与 $parent / $children 适用 父子组件通信

3)、EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信

通过一个空的Vue实例作为中央事件总线,用它来触发事件和监听事件

4)、$ attrs/$listeners 适用于 隔代组件通信

简单来说:$ attrs与$ listeners 是两个对象,$ attrs 里存放的是父组件上绑定的非 Props 属性,$ listeners里存放的是父组件中绑定的非原生事件。

5)、provide / inject 适用于 隔代组件通信

祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。

6)、Vuex 适用于 父子、隔代、兄弟组件通信

29、vue 组件的data 为什么是一个函数

组件是可复用的,一个组件被创建好之后,就可能被用在各个地方,而组件不管被复用了多少次,组件中的 data 数据都应该是相互隔离,互不影响的,基于这一理念,组件每复用一次,data 数据就应该被复制一次,之后,当某一处复用的地方组件内 data 数据被改变时,其他复用地方组件的 data 数据不受影响.

组件中的 data 写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的 data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份 data,就会造成一个变了全都会变的结果。(对象为引用类型,当重用组件时,由于数据对象都指向同一个data对象,当在一个组件中修改data时,其他重用的组件中的data会同时被修改;而使用返回对象的函数,由于每次返回的都是一个新对象(Object的实例),引用地址不同,则不会出现这个问题)

30、data 里面数据量比较大如何优化

vue 把 data、props、store 等数据做成响应式,也就是会对这些响应式数据做深度监听,给每一个object类型的key(包括嵌套object)添加observer(vue3使用proxy)。所以如果我们不需要数据是响应式的,可以在.vue 文件头部直接使用 let、const 定义变量,在组件销毁的时候将该这些变量设为null。

31、子组件里面可以修改父组件的值吗

答案是传递的是对象和数组可以修改,如果是基础数据类型也可以修改,但是控制台会报错;对象和数组修改之后父组件是可以监听到这个值的变化的。那么为什么呢?

对象和数组都是引用类型,父组件传递过来的是一个地址,子组件修改的是地址里面的内容,地址本身并没有变,所以不会报错,但是基础数据类型就不同了,他是直接修改了传递的值,但是 vue 不允许在子组件里面直接修改prop值,所以就会报错。

32、生命周期钩子是如何实现的

Vue的生命周期钩子就是回调函数而已,当创建组件实例的过程中会调用对应的钩子方法。

内部主要是使用callHook方法来调用对应的方法。核心是一个发布订阅模式,将钩子订阅好(内部采用数组的方式存储),在对应的阶段进行发布。

33、什么是 vue-loader

作用:解析和转换.vue文件。提取出其中的逻辑代码 script,样式代码style,以及HTML 模板template,再分别把他们交给对应的loader去处理

用途:js可以写es6,style样式可以写scss或less

特性:

1、允许为 Vue 组件的每个部分使用其它的 webpack loader,例如在

34、vue 是怎么检测数组的变化的

流程:

35、vue 是怎样依赖收集的?(dep 和 Watcher 是什么关系)

注意:Dep 是一个用来负责收集 Watcher 的类,Watcher 是一个封装了渲染视图逻辑的类,用于派发更新的。Watcher 是不能直接更新视图的还需要结合 vdom 经过 patch() 中的 diff 算法才可以生成真正的 DOM

36、vue路由的钩子函数(导航守卫)

37、vue $route 和 $router 的区别

38、vue 中的 diff 算法原理

diff 算法的原理是递归加上遍历节点来比较节点复用性。diff 算法通过对比虚拟树的差异,将差异通过 patch (补丁)一边比较一边打补丁方式更新到真实 dom 节点上。patch 函数是 diff 流程的入口函数。在采取diff算法比较新旧节点的时候,比较只会在同层级进行, 不会跨层级比较。

在数据发生变化的时候,set 方法就会调用 dep.notify 通知所有订阅者,订阅者会调用 patch 给真实的 dom 打补丁,更新相应的视图。

更详细内容参考

39、Vue. extend 能做什么

作⽤是扩展组件⽣成⼀个构造器,通常会与 $mount ⼀起使⽤。

<div id="mount-point"> 
     div> 
// 创建构造器 var Profile = Vue.extend({ template: '<p>{ 
  {firstName}} { 
  {lastName}} aka { 
  {alias}} 
     p>', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount('#mount-point') 

这样div里面就有了下面内容

<p>Walter White aka Heisenberg 
     p> 

40、vue 的 mixin 和 mixins 区别

41、vue 组件渲染和更新的过程

渲染:

更新:

42、vue 为什么采用异步渲染

因为如果不采用异步更新,那么每次更新数据都会对当前组件进行重新渲染;所以为了性能考虑,Vue会在本轮数据更新后,再去异步更新视图。

原理:

43、vue 为什么要使用异步组件

原理:在createComponent方法中,会有相应的异步组件处理

44、vue 如何快速定位那个组件出现性能问题的

⽤ timeline ⼯具。 通过 timeline 来查看每个函数的调⽤时常,定位出哪个函数的问题,从⽽能判断哪个组件出了问题

45、vue3.x 对比 vue2.x 变化

https://blog.csdn.net/r/article/details/

46、watch 的 deep 如何实现的

watch 在监听对象的时候,如果 deep 值是 true,就会执行 traverse 这个方法,这个方法里就是做了个数组递归,如果是数组的话,会根据数组的每一项索引取值,进行递归追加依赖,如果是对象会拿 key 进行遍历取值,进行递归追加依赖,traverse 就是deep:true实现的核心。这样就会把数组或者对象的每一个属性都追加依赖进行监听,只要依赖发生变化就会通知视图更新。

47、v-html 会导致那些问题

48、v-el作用

提供一个在页面上已存在的 DOM元素作为 Vue实例的挂载目标.可以是 CSS 选择器,也可以是一个 HTMLElement 实例,

48、说说vue的动态组件

<div id="app"> <component is="one"> 
     component>  
      div> new Vue({ el: '#app', components: { one: {template: '<div>我是线路一 
       div>'}, two: {template: '<div>我是线路二 
        div>'}, thr: {template: '<div>我是线路三 
         div>'} } }) 

49、怎么定义vue-router的动态路由?怎么获取传过来的值?

//index.js path:'/user/:id', compunent: user 
// 方法1: <router-link :to="{ name: 'users', params: { id: 123}}">按钮 
     router-link> // 方法2: this.$router.push({name:'users',params:{id:123}}) // 方法3: this.$router.push('/user/' + 123) 

2)、query:不需要配置路由格式,使用 router 对象的 query.id 获取。

// 方法1: <router-link :to="{ name: 'users', query: { id: 123}}">按钮 
     router-link> // 方法2: this.$router.push({ name: 'users', query:{ id:123}}) // 方法3: <router-link :to="{ path: '/user', query: { id:123 }}">按钮 
      router-link> // 方法4: this.$router.push({ path: '/user', query:{ id:123 }}) // 方法5: this.$router.push('/user?uname=' + 123) 

50、自定义指令

自定义指令的生命周期,有5个事件钩子,可以设置指令在某一个事件发生时的具体行为:

钩子函数的参数 (包括 el,binding,vnode,oldVnode)

51、自定义过滤器

参考:vue 全局注册过滤器 filter

52、vue 中 extend、mixins、extends的区别

1)、extend:使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件对象。

2)、mixins:可以混入多个,当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

var vm = new Vue({ created: function () { console.log(3) }, mixins: [mixinA ,mixinB ] }) 

3)、extends:声明扩展另一个组件(可以是一个简单的选项对象或构造函数)无需使用 Vue.extend。这主要是为了便于扩展单文件组件。和 mixins 类似。但extends只能继承一个。

var otherComp= { ... } // 继承 otherComp var comp = { extends: otherComp, ... } 

总结:

以上是我总结的 VUE 相关的知识点,还会继续更新,如有错误或者遗漏的地方欢迎指正!!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/228854.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午6:02
下一篇 2026年3月16日 下午6:03


相关推荐

  • pycharm安装CV2,tensorflow[通俗易懂]

    pycharm安装CV2,tensorflow[通俗易懂]在pycharm中导入importcv2时不能正常使用,需要安装cv2库,但是我们在pycharm中安装库时没有找到CV2,就需要安装opencv库,我采用的是以下的方式:1、首先看下pycharm中的环境,我现在用的环境是anaconda下的PyCharmproject2、在菜单栏中打开anacondaprompt(anaconda3)3、刚开始进入时环境是4、切换环境为pycharm中环境activatePyCharmproject5、已经下好了opencv的whl文件,我下到了3

    2022年8月26日
    11
  • Java关键字及其作用详解

    Java关键字及其作用详解Java 中的关键字有如下表格中这么多下面分别解释一下每个关键字的含义 private 一种访问控制方式 私用模式 protected 一种访问控制方式 保护模式 public 一种访问控制方式 共用模式 abstract 表明类或者成员方法具有抽象属性 class 类 extends 表明一个类型是另一个类型的子类型 这里常见的类

    2026年3月18日
    2
  • 现场总线及其应用「建议收藏」

    现场总线及其应用「建议收藏」现场总线是应用在生产现场、在微机化测量控制设备之间实现双向串行多节点数字通信的系统,也被称为开放式、数字化、多点通信的底层控制网络。现场总线技术形成了真正分散在现场的完整控制系统,提高了控制系统运行的可靠性,丰富了控制设备的信息内容。为控制信息进入公用数据网络创造了条件,沟通了现场控制设备之间及其与更高控制管理层网络之间的联系,便于实现管控一体化,同时控制网络与数据网络的结合,便于实现信号的远程传…

    2022年5月10日
    53
  • Mongo的morphia读取Map<String>>类型数据的问题「建议收藏」

    Mongo的morphia读取Map<String>>类型数据的问题「建议收藏」      最近一直使用morphia,给mongo数据查询带来很多遍历,但是最近项目遇到了一个严重的问题,在从Mongo数据库中查询Map&lt;String, List&lt;Object&gt;&gt;字段时,针对value值为空list时(即[ ]),竟然读到数据的严重问题,具体描述如下: 1.Entity数据结构:      import org.mongodb.morph…

    2022年6月17日
    44
  • SplitContainer控件设置固定比例

    SplitContainer控件设置固定比例SplitContainer控件2个panel如何设置均等大小.(竖直拆分)先随意设置空间高的大小,然后如果想要均等显示,则直接设置SplitterDistance为高的一半,即可!随后任意改变控件大小,都不会改变均等显示比例。同理3:7,4:6…

    2022年7月18日
    15
  • java 长轮询_基于springboot 长轮询的实现操作

    java 长轮询_基于springboot 长轮询的实现操作springboot长轮询实现基于@EnableAsync,@Sync@SpringBootApplication@EnableAsyncpublicclassDemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DemoApplication.class,args);}}@Req…

    2022年10月14日
    5

发表回复

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

关注全栈程序员社区公众号