2024前端面试准备4-Vue相关

Vue2.0


1. 双向绑定原理
Vue是采用数据劫持+发布订阅模式的方式,通过Object.defienProperty()来劫持各个属性的setter\getter,在数据发送变动时发布消息给订阅者,触发相应的监听回调。主要分为以下几个步骤:

  • observe的数据对象进行递归遍历,包括子属性对象的属性,都是加速setter\getter,这样给这个对象某个值赋值,都会触发setter,就能监控到数据的变化。
  • compile解析模版指令,将模版中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦有数据变动,收到通知,更新视图。
  • Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是: ①在自身实例化时往属性订阅器(dep)里面添加自己 ②自身必须有一个update()方法 ③待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调。
  • MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

2.使用 Object.defineProperty() 来进行数据劫持有什么缺点?
有些操作无法监听,例如:通过下标改数组数据,理论上来说大部分数组操作都拦不到,只是Vue内部通过重写函数的方式解决了一部分问题。3.0中采用proxy对对象做代理,从而实现数据劫持,不会有这个问题,但是有个缺点就是Proxy时ES6语法,兼容性差一点。

3. 什么是MVVM?
MVVM 分为 Model、View、ViewModel:
● Model代表数据模型,数据和业务逻辑都在Model层中定义;
● View代表UI视图,负责数据的展示;
● ViewModel负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作;
Model和View并无直接关联,而是通过ViewModel来进行联系的,Model和ViewModel之间有着双向数据绑定的联系。因此当Model中的数据改变时会触发View层的刷新,View中由于用户交互操作而改变的数据也会在Model中同步。

4. Computed 和Watch的区别
computed有缓存机制,依赖其他数值,只有依赖的属性值发生改变,下次获取computed的值才会重新计算,当需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时都要重新计算。watch更多的是观察机制,无缓存性,只要监听的对象发生变化,都会执行回调进行后续操作。当需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许执行异步操作,限制执行该操作的频率,并在得到最终结果前,设置中间状态

5. v-if和v-show的区别

  • v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显隐;
  • v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;
  • v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译; v-show是在任何条件下,无论首次条件是否为真,都被编译,然后被缓存,而且DOM元素保留;-
  • v-if有更高的切换消耗;v-show有更高的初始渲染消耗;
  • v-if适合运营条件不大可能改变;v-show适合频繁切换。

6.data为什么是一个函数而不是对象
Vue组件可能会被实例化多次,如果使用对象,多个实例将共用一个data对象,状态的改变会影响到所有的实例,用函数形式,在组件实例化是返回的都是一个全新的对象,不存在实例之间状态污染问题。

7. 对keep-alive的理解,它是如何实现的,具体缓存的是什么
keep-alive 经常与动态组件和router-view组件搭配使用,主要作用是在组件切换时候,保存一些组件状态防止多次渲染,减少加载时间及性能消耗,提高用户体验性。原理就是在created函数调用时将需要换成的Vnode节点保存在this.cache中,在页面渲染时,如果Vnode的name符合缓存条件,则会从this.cache中取出之间缓存的Vnode实例进行渲染。

8.$nextTick原理及作用
nextTick其本质是对JS事件循环的一种应用。核心就是例用Prosime, 定时器等原生方法来模拟对应的微/宏任务的实现,为了利用JS的这些异步回调任务队列,实现Vue框架中自己的异步回调队列。
常用场景:

  • 在数据变化后执行的某个操作,而这个操作需要使用随数据变化而变化的DOM结构的时候,这个操作就需要方法在nextTick()的回调函数中。
  • 在vue生命周期中,如果在created()钩子进行DOM操作,也一定要放在nextTick()的回调函数中

9. Vue data 中某一个属性的值发生改变后,视图会立即同步执行重新渲染吗?
不会理解同步执行重新渲染,而是按照一定策略进行更新,Vue在更新DOM时是异步的,只要监听到数据变化,Vue会开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。跟react的setState有异曲同工之妙。
如果同一个watcher被多次触发,只会被推入到队列一次,这种在缓冲时去除重复数据对于避免不必要的计算和DOM操作是非常重要的。然后,在下一个事件循环中,Vue刷新队列并执行已去重的实际工作,十分节省性能。

10.描述下Vue自定义指令
自定义指令通常用于对普通DOM元素进行底层操作时使用,建议只用于对dom的操作或者样式的修改。比方说按钮权限显隐、防抖节流、点击放大缩小这种操作

11.子组件可以直接改变父组件的数据吗?
子组件不可以直接改变父组件数据,Vue提倡单向数据流,即父级props的更新流向子组件,反过来则不行, 只能通过$emit是派发一个自定义事件,父组件接收到后,由父组件自己修改。

12.对 React 和 Vue 的理解,它们的异同
相似之处:

  • 都将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库;
  • 都有自己的构建工具,能让你得到一个根据最佳实践设置的项目模板;
  • 都使用了Virtual DOM(虚拟DOM)提高重绘性能;
  • 都有props的概念,允许组件间的数据传递;
  • 都鼓励组件化应用,将应用分拆成一个个功能明确的模块,提高复用性。

不同之处 :
1)数据流
Vue默认支持数据双向绑定,而React一直提倡单向数据流
2)虚拟DOM**
Vue2.x开始引入"Virtual DOM",消除了和React在这方面的差异,但是在具体的细节还是有各自的特点。

  • Vue宣称可以更快地计算出Virtual DOM的差异,这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。
  • 对于React而言,每当应用的状态被改变时,全部子组件都会重新渲染。当然,这可以通过 PureComponent/shouldComponentUpdate这个生命周期方法来进行控制,但Vue将此视为默认的优化。

3)组件化
React与Vue最大的不同是模板的编写。

  • Vue鼓励写近似常规HTML的模板。写起来很接近标准 HTML元素,只是多了一些属性。
  • React推荐你所有的模板通用JavaScript的语法扩展——JSX书写。
    具体来讲:React中render函数是支持闭包特性的,所以import的组件在render中可以直接调用。但是在Vue中,由于模板中使用的数据都必须挂在 this 上进行一次中转,所以 import 一个组件完了之后,还需要在 components 中再声明下。
    4)监听数据变化的实现原理不同
  • Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化,不需要特别的优化就能达到很好的性能
  • React 默认是通过比较引用的方式进行的,如果不优化(PureComponent/shouldComponentUpdate)可能导致大量不必要的vDOM的重新渲染。这是因为 Vue 使用的是可变数据,而React更强调数据的不可变。

5)高阶组件
react可以通过高阶组件(HOC)来扩展,而Vue需要通过mixins来扩展。

高阶组件就是高阶函数,而React的组件本身就是纯粹的函数,所以高阶函数对React来说易如反掌。相反Vue.js使用HTML模板创建视图组件,这时模板无法有效的编译,因此Vue不能采用HOC来实现。

6)构建工具
两者都有自己的构建工具:

  • React ==> Create React APP
  • Vue ==> vue-cli

7)跨平台

  • React ==> React Native
  • Vue ==> Weex

13.assets和static的区别
assets和static都是存放静态资源文件例如图片,字体,样式等。assets在编译打包时会走压缩、格式化流程,打包后的文件会放在sataic中一起输出。static中不会走打包流程,放进去的什么样,build完还是什么样。

14. 什么是 mixin

  • Mixin 使我们能够为 Vue 组件编写可插拔和可重用的功能。
  • 如果希望在多个组件之间重用一组组件选项,例如生命周期 hook、 方法等,则可以将其编写为 mixin,并在组件中简单的引用它。
  • 然后将 mixin 的内容合并到组件中。如果你要在 mixin 中定义生命周期 hook,那么它在执行时将优化于组件自已的 hook。

15. Vue模版编译原理
template不是浏览器标准,所以无法直接被浏览器解析并渲染,要经过编译、转化才行。解析时用大量的正则表达式对其进行解析,将标签、指令、属性等转化为抽象语法树AST,然后遍历AST找到一些静态节点并标记,方便页面重渲染时候继续diff比较,直接跳过这一些静态节点,优化runtime等性能,将最终的AST转化为可渲染的render函数字符串。

16.Vue的性能优化有哪些?

  • 编码阶段(减少data中的数据、v-if和v-for不要一起用、keep-alive缓存组件、多使用懒加载、异步组件、防抖、节流、第三方模块按需引入)
  • SEO优化 预渲染、SSR
  • 打包优化(压缩代码、使用CDN加载第三方、splitChunks抽离公共文件)
  • 用户体验(骨架屏、PWA、多使用缓存、服务器gzip压缩)

17.一般在哪个生命周期请求异步数据?
推荐在 created 钩子函数中调用异步请求,能更快获取到服务器数据,减少页面加载时间,而且SSR并不支持mounted钩子函数,放在created中更有一致性。

18.组件之间有哪些通信方法
1)父子组件间通信
● 子组件通过 props 属性来接受父组件的数据,然后父组件在子组件上注册监听事件,子组件通过 emit 触发事件来向父组件发送数据。
● 通过 ref 属性给子组件设置一个名字。父组件通过 $refs 组件名来获得子组件,子组件通过 $parent 获得父组件,这样也可以实现通信。
● 使用 provide/inject,在父组件中通过 provide提供变量,在子组件中通过 inject 来将变量注入到组件中。不论子组件有多深,只要调用了 inject 那么就可以注入 provide中的数据。
2)兄弟组件间通信
● 使用 eventBus 的方法,它的本质是通过创建一个空的 Vue 实例来作为消息传递的对象,通信的组件引入这个实例,通信的组件通过在这个实例上监听和触发事件,来实现消息的传递。
● 通过 p a r e n t / parent/ parent/refs 来获取到兄弟组件,也可以进行通信。
3)任意组件之间
● 使用 eventBus ,其实就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。

** 19.Vue-router跳转和location.href有什么区别?**
location.href会刷新页面,router.push 不会刷新页面,静态跳转,使用了 diff 算法,实现了按需加载,减少了 dom 的消耗,内部采用了history.pushState()。

20.说一下Vuex
Vuex 是一个专为 Vue 应用程序开发的状态管理模式,Vuex实现了一个单向数据流,每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。Vuex在全局拥有一个State存放数据,当组件要改变State中数据时,必须通过Mutation提交修改信息,Mu tation同时还提供了订阅者模式供外部插件调用获取State数据的更新。而异步操作或者批量的同步操作要走Action,Action无法直接修改State,还是需要通过Mu tation来修改,最后根据State的变化,渲染到视图上。

21.为什么 Vuex 的 mutation 中不能做异步操作?
每个mutation执行完成后都会对应到一个新的状态变更,如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。


Vue 3.0

1.Vue3.0有什么更新

  • 监测机制的改变 3.0采用了基于proxy的订阅方式,消除了2.0存在的很多限制
  • 只能监测属性,不能监测对象
  • 模版变化:作用域插槽,2.0的机制导致作用域插槽变了,父组件会重新渲染,3.0把作用域插槽改成了函数的方式,只会影响子组件重新渲染,提高了渲染的性能。
  • 组件声明方式:3.0修改了组件的声明方式,改成了类式的写法,这样使TS的结合更容易。

2.defineProperty和proxy的区别
Object.defineProperty 在添加和删除对象属性时,Vue监测不到,因为添加或删除的对象没有在初始化进行响应式处理,只能通过$set来调用Object.defineProperty来处理。同时也无法监控到数组下标和长度的变化。
Proxy直接代理整个对象而非对象属性,这样只需要做一层代理就可以监听同级结构下的所有属性变化,包括新增属性和删除属性,同时也能监听到数组的变化。

3. Composition API与React Hook很像,区别是什么?
从React Hook的实现角度看,React Hook是根据useState调用的顺序来确定下一次重渲染时的state是来源于哪个useState,所以出现了以下限制

  • 不能在循环、条件、嵌套函数中调用Hook
  • 必须确保总是在你的React函数的顶层调用Hook
  • useEffect、useMemo等函数必须手动确定依赖关系
    而Composition API是基于Vue的响应式系统实现的,与React Hook的相比:
  • 声明在setup函数内,一次组件实例化只调用一次setup,而React Hook每次重渲染都需要调用Hook,使得React的GC比Vue更有压力,性能也相对于Vue来说也较慢
  • Compositon API的调用不需要顾虑调用顺序,也可以在循环、条件、嵌套函数中使用
  • 响应式系统自动实现了依赖收集,进而组件的部分的性能优化由Vue内部自己完成,而React Hook需要手动传入依赖,而且必须必须保证依赖的顺序,让useEffect、useMemo等函数正确的捕获依赖变量,否则会由于依赖不正确使得组件性能下降。
    虽然Compositon API看起来比React Hook好用,但是其设计思想也是借鉴React Hook的。

4.对虚拟DOM的理解?
本质上来讲,vDOM是一个JS对象,通过对象的方式表达DOM结构,配合不同的渲染工具,使跨平台渲染成为可能(SSR、UniApp)。通过事务处理机制,将多次DOM修改的结果,真正的差异部分,一次性的更新到页面上,从而有效的减少页面的渲染次数,减少修改DOM的重排重绘次数,提高了渲染的性能。

5.DIFF算法原理

  • 首先对比节点本身,是否是同一节点,如果不为相同节点,则删除该节点重新创建节点进行替换
  • 如果为同一节点,接着判断一方有子节点一方没子节点情况,如果新的没有子节点,就把旧的子节点移除,旧的没有新的有则添加
  • 如果新旧都有子节点,则进行子节点更新,判断如何对这些新老节点的子老节点的子节点进行操作(diff核心)
  • 匹配时,找到相同的子节点,递归比较子节点
    在diff中,只对同层的子节点进行比较,放弃跨级的节点比较,也就是说,只有当新旧children都为多个子节点时才需要用核心的Diff算法进行同层级比较。

相关推荐

  1. 2024前端面试准备4-Vue相关

    2024-06-10 10:02:01       16 阅读
  2. 2024前端面试准备5-React相关

    2024-06-10 10:02:01       15 阅读
  3. 2024前端面试准备Vue3篇

    2024-06-10 10:02:01       44 阅读
  4. 2024前端面试准备之HTML篇

    2024-06-10 10:02:01       34 阅读
  5. 2024前端面试准备之uniapp篇

    2024-06-10 10:02:01       36 阅读
  6. 2024前端面试准备-HTML&CSS

    2024-06-10 10:02:01       13 阅读
  7. 2024前端面试准备6-TS基础

    2024-06-10 10:02:01       15 阅读
  8. 2024前端面试准备之TypeScript篇(一)

    2024-06-10 10:02:01       39 阅读
  9. 2024前端面试准备之CSS篇(二)

    2024-06-10 10:02:01       41 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-10 10:02:01       5 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-10 10:02:01       5 阅读
  3. 在Django里面运行非项目文件

    2024-06-10 10:02:01       4 阅读
  4. Python语言-面向对象

    2024-06-10 10:02:01       6 阅读

热门阅读

  1. #10 解决Stable Diffusion常见问题和错误

    2024-06-10 10:02:01       19 阅读
  2. 006 CentOS 7.9 elasticsearch7.10.0安装及配置

    2024-06-10 10:02:01       15 阅读
  3. 1341. 电影评分

    2024-06-10 10:02:01       18 阅读
  4. 如何学好量子计算机技术的两种思路

    2024-06-10 10:02:01       12 阅读
  5. 爬山算法详细介绍

    2024-06-10 10:02:01       20 阅读