2021Vue.js面试题汇总及答案【全网最全 建议收藏】(一)

简介: 2021Vue.js面试题汇总及答案【全网最全 建议收藏】

一、Vue.js基本问题


1.1.Vue 响应式原理


7d076ce787bd4f9cb3b2564d847bb3b4.png

核心实现类:


Observer : 它的作用是给对象的属性添加 getter 和 setter,用于依赖收集和派发更新

Dep : 用于收集当前响应式对象的依赖关系,每个响应式对象包括子对象都拥有一个 Dep 实例(里面 subs 是 Watcher 实例数组),当数据有变更时,会通过 dep.notify()通知各个 watcher。


Watcher : 观察者对象 , 实例分为渲染 watcher (render watcher),计算属性 watcher (computed watcher),侦听器 watcher(user watcher)三种


Watcher 和 Dep 的关系:


watcher 中实例化了 dep 并向 dep.subs 中添加了订阅者,dep 通过 notify 遍历了 dep.subs 通知每个 watcher 更新。


依赖收集:


initState 时,对 computed 属性初始化时,触发 computed watcher 依赖收集


initState 时,对侦听属性初始化时,触发 user watcher 依赖收集


render()的过程,触发 render watcher 依赖收集


re-render 时,vm.render()再次执行,会移除所有 subs 中的 watcer 的订阅,重新赋值。


派发更新:


组件中对响应的数据进行了修改,触发 setter 的逻辑


调用 dep.notify()


遍历所有的 subs(Watcher 实例),调用每一个 watcher 的 update 方法。


原理:


当创建 Vue 实例时,vue 会遍历 data 选项的属性,利用 Object.defineProperty 为属性添加 getter 和 setter 对数据的读取进行劫持(getter 用来依赖收集,setter 用来派发更新),并且在内部追踪依赖,在属性被访问和修改时通知变化。


每个组件实例会有相应的 watcher 实例,会在组件渲染的过程中记录依赖的所有数据属性(进行依赖收集,还有 computed watcher,user watcher 实例),之后依赖项被改动时,setter 方法会通知依赖与此 data 的 watcher 实例重新计算(派发更新),从而使它关联的组件重新渲染。


一句话总结:


vue.js 采用数据劫持结合发布-订阅模式,通过 Object.defineproperty 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发响应的监听回调


1.2.Vue.js 的特点


易用: 简单,易学,上手快


灵活: (渐进式)不断繁荣的生态系统,可以在一个库和一套完整框架之间自如伸缩。


高效: 20kB min+gzip 运行大小;超快虚拟 DOM;最省心的优化


双向绑定:开发效率高


基于组件的代码共享


Web项目工程化,增加可读性、可维护性


1.3. Vue.js 双向绑定的原理


Vue.js 2.0 采用数据劫持(Proxy 模式)结合发布者-订阅者模式(PubSub 模式)的方式,通过 Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。


每个组件实例都有相应的watcher程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新。


Vue.js 3.0, 放弃了Object.defineProperty ,使用更快的ES6原生 Proxy (访问对象拦截器, 也称代理器)


步骤:


1.需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化


2.compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图


3.Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是: ①在自身实例化时往属性订阅器(dep)里面添加自己 ②自身必须有一个update()方法 ③待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。


4.MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。


1.4.Vue中如何监控某个属性值的变化?


比如现在需要监控data中, obj.a 的变化。Vue中监控对象属性的变化你可以这样:

watch: {
      obj: {
        handler (newValue, oldValue) {
        console.log('obj changed')
      },
      deep: true
    }

deep属性表示深层遍历,但是这么写会监控obj的所有属性变化,并不是我们想要的效果,所以做点修改:

watch: {
   'obj.a': {
        handler (newName, oldName) {
        console.log('obj.a changed')
      }
   }
  }

还有一种方法,可以通过computed 来实现,只需要:

computed: {
    a1 () {
      return this.obj.a
    }
}

利用计算属性的特性来实现,当依赖改变时,便会重新计算一个新值。


1.5.Vue.js 3.0 放弃defineProperty, 使用Proxy的原因


Object.defineProperty缺陷


1.监控到数组下标的变化时,开销很大。所以Vue.js放弃了下标变化的检测;


2.Object.defineProperty只能劫持对象的属性,而Proxy是直接代理对象。


3.Object.defineProperty需要遍历对象的每个属性,如果属性值也是对象,则需要深度遍历。而 Proxy 直接代理对象,不需要遍历操作。


4.Object.defineProperty对新增属性需要手动进行Observe。vue2时需要使用 vm.$set 才能保证新增的属性也是响应式


5.Proxy支持13种拦截操作,这是defineProperty所不具有的


6.Proxy 作为新标准,长远来看,JS引擎会继续优化 Proxy,但 getter 和 setter 基本不会再有针对性优化


1.6.Vue 2 中给 data 中的对象属性添加一个新的属性时会发生什么?如何解决?


视图并未刷新。这是因为在Vue实例创建时,新属性并未声明,因此就没有被Vue转换为

响应式的属性,自然就不会触发视图的更新,这时就需要使用Vue的全局 api $set():


this.$set(this.obj, 'new_property', 'new_value')

1.7.Computed和Watch的区别及运用场景


computed 计算属性 : 依赖其它属性值,并且 computed 的值有缓存,只有它依赖的 属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。


watch 侦听器 : 更多的是观察的作用,无缓存性,类似于某些数据的监听回调,每 当监听的数据变化时都会执行回调进行后续操作。


运用场景:


1.当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算。


2.当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率, 并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。


3.多个因素影响一个显示,用Computed;一个因素的变化影响多个其他因素、显示,用Watch;


1.8. Computed 和 Methods 的区别


1.computed: 计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值对于 method ,只要发生重新渲染,


2.method 调用总会执行该函数


1.9.虚拟DOM,diff算法


1.让我们不用直接操作DOM元素,只操作数据便可以重新渲染页面


2.虚拟dom是为了解决浏览器性能问题而被设计出来的

当操作数据时,将改变的dom元素缓存起来,都计算完后再通过比较映射到真实的dom树上


3.diff算法比较新旧虚拟dom。如果节点类型相同,则比较数据,修改数据;如果节点不同,直接干掉节点及所有子节点,插入新的节点;如果给每个节点都设置了唯一的key,就可以准确的找到需要改变的内容,否则就会出现修改一个地方导致其他地方都改变的情况。比如A-B-C-D, 我要插入新节点A-B-M-C-D,实际上改变的了C和D。但是设置了key,就可以准确的找到B C并插入


1.10.为何需要Virtual DOM?


1.具备跨平台的优势


2.操作 DOM 慢,js运行效率高。我们可以将DOM对比操作放在JS层,提高效率。


3.提升渲染性能


1.11.过滤器 (Filter)


在Vue中使用filters来过滤(格式化)数据,filters不会修改数据,而是过滤(格式化)数据,

改变用户看到的输出(计算属性 computed ,方法 methods 都是通过修改数据来处理数据格式的输出显示。


使用场景: 比如需要处理时间、数字等的的显示格式;


1.12.常见的事件修饰符及其作用


1).stop:等同于 JavaScript 中的 event.stopPropagation() ,防止事件冒泡;


2).prevent :等同于 JavaScript 中的 event.preventDefault() ,防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播);


3).capture :当元素发生冒泡时,先触发带有该修饰符的元素。若有多个该修饰符,则由

外而内触发。如 div1中嵌套div2中嵌套div3.capture中嵌套div4,那么执行顺序为:div3=》div4=》div2=》div1


4).self :只会触发自己范围内的事件,不包含子元素;


5).once :只会触发一次。


1.13.v-show指令和v-if指令的区别是什么?


v-show 仅仅控制元素的显示方式,将 display 属性在 block 和 none 来回切换;而v-if会控制这个 DOM 节点的存在与否。当我们需要经常切换某个元素的显示/隐藏时,使用v-show会更加节省性能上的开销;当只需要一次显示或隐藏时,使用v-if更加合理。


1.14.v-model 是如何实现的,语法糖实际是什么


作用在表单元素上v-model="message"等同于v-bind:value=“message” v-on:input="message=e v e n t . t a r g e t . v a l u e " 作 用 在 组 件 上 , 本 质 是 一 个 父 子 组 件 通 信 的 语 法 糖 , 通 过 p r o p 和 event.target.value" 作用在组件上, 本质是一个父子组件通信的语法糖,通过prop和event.target.value"作用在组件上,本质是一个父子组件通信的语法糖,通过prop和.emit实现, 等同于:value="message" @input=" $emit('input', $event.target.value)"


1.15.data为什么是一个函数而不是对象


JavaScript中的对象是引用类型的数据,当多个实例引用同一个对象时,只要一个实例对这个对象进行操作,其他实例中的数据也会发生变化。


而在Vue中,我们更多的是想要复用组件,那就需要每个组件都有自己的数据,这样组件之间才不会相互干扰。


所以组件的数据不能写成对象的形式,而是要写成函数的形式。数据以函数返回值的形式定义,这样当我们每次复用组件的时候,就会返回一个新的data,也就是说每个组件都有自己的私有数据空间,它们各自维护自己的数据,不会干扰其他组件的正常运行。


1.16.Vue template 到 render 的过程


1.调用parse方法将template转化为ast(抽象语法树, abstract syntax tree)


2.对静态节点做优化。如果为静态节点,他们生成的DOM永远不会改变,这对运行时模板更新起到了极大的优化作用。


3.生成渲染函数. 渲染的返回值是VNode,VNode是Vue的虚拟DOM节点,里面有(标签名,子节点,文本等等)


1.17.Vue template 到 render 的过程


调用parse方法将template转化为ast(抽象语法树, abstract syntax tree)

对静态节点做优化。如果为静态节点,他们生成的DOM永远不会改变,这对运行时模板更新起到了极大的优化作用。


生成渲染函数. 渲染的返回值是VNode,VNode是Vue的虚拟DOM节点,里面有(标签名,子节点,文本等等)


1.18.axios是什么


易用、简洁且高效的http库, 支持node端和浏览器端,支持Promise,支持拦截器等高级配置。


1.19.sass是什么?如何在vue中安装和使用?


sass是一种CSS预编译语言安装和使用步骤如下。


1.用npm安装加载程序( sass-loader、 css-loader等加载程序)。

2.在 webpack.config.js中配置sass加载程序。


1.20.Vue.js页面闪烁


Vue. js提供了一个v-cloak指令,该指令一直保持在元素上,直到关联实例结束编译。当和CSS一起使用时,这个指令可以隐藏未编译的标签,直到实例编译结束。用法如下


1.21.如何解决数据层级结构太深的问题


在开发业务时,经常会岀现异步获取数据的情况,有时数据层次比较深,如以下代码: <span 'v-text=“a.b.c.d”>, 可以使用vm.$set手动定义一层数据:


vm.$set("demo",a.b.c.d)


1.22.在 Vue. js开发环境下调用API接口,如何避免跨域

config/ index.js内对 proxyTable项配置代理。

目录
相关文章
|
4月前
|
JSON JavaScript 前端开发
Javascript基础 86个面试题汇总 (附答案)
该文章汇总了JavaScript的基础面试题及其答案,涵盖了JavaScript的核心概念、特性以及常见的面试问题。
67 3
|
4月前
|
前端开发 JavaScript
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
|
5月前
|
JavaScript 前端开发 应用服务中间件
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
这篇文章分析了Vue项目在服务器部署后出现404错误的原因,主要是由于history路由模式下服务器缺少对单页应用的支持,并提供了通过修改nginx配置使用`try_files`指令重定向所有请求到`index.html`的解决方案。
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
|
5月前
|
JavaScript 前端开发
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
这篇文章主要讨论了axios的使用、原理以及源码分析。 文章中首先回顾了axios的基本用法,包括发送请求、请求拦截器和响应拦截器的使用,以及如何取消请求。接着,作者实现了一个简易版的axios,包括构造函数、请求方法、拦截器的实现等。最后,文章对axios的源码进行了分析,包括目录结构、核心文件axios.js的内容,以及axios实例化过程中的配置合并、拦截器的使用等。
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
|
5月前
|
JavaScript 前端开发 数据处理
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
这篇文章讨论了Vue中实现权限管理的策略,包括接口权限、路由权限、菜单权限和按钮权限的控制方法,并提供了不同的实现方案及代码示例,以确保用户只能访问被授权的资源。
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
|
5月前
|
JavaScript 前端开发
【Vue面试题二十七】、你了解axios的原理吗?有看过它的源码吗?
文章讨论了Vue项目目录结构的设计原则和实践,强调了项目结构清晰的重要性,提出了包括语义一致性、单一入口/出口、就近原则、公共文件的绝对路径引用等原则,并展示了单页面和多页面Vue项目的目录结构示例。
|
2月前
|
JSON JavaScript 前端开发
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
本文介绍了JSONP的工作原理及其在解决跨域请求中的应用。首先解释了同源策略的概念,然后通过多个示例详细阐述了JSONP如何通过动态解释服务端返回的JavaScript脚本来实现跨域数据交互。文章还探讨了使用jQuery的`$.ajax`方法封装JSONP请求的方式,并提供了具体的代码示例。最后,通过一个更复杂的示例展示了如何处理JSON格式的响应数据。
40 2
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
|
4月前
|
缓存 JavaScript 前端开发
vue面试题
vue面试题
174 64
|
3月前
|
JavaScript 前端开发
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
47 0
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
|
3月前
|
Web App开发 JavaScript 前端开发
前端Node.js面试题
前端Node.js面试题

热门文章

最新文章