前端面试题-vue

256 阅读7分钟

1、SPA的理解,有什么优缺点?

SPA(单页应用)是一种前端应用程序的架构模式,它通过在加载应用程序时只加载单个 HTML 页面,并通过使用 JavaScript 动态地更新页面内容,从而实现无刷新的用户体验。

优点

  • 用户体验SPA 提供了流畅、快速的用户体验,在页面加载后,只有需要的数据和资源会被加载,减少了页面刷新的延迟。
  • 响应式交互:由于 SPA 依赖于异步数据加载和前端路由,可以实现实时更新和动态加载内容,使用户可以快速地与应用程序交互。
  • 代码复用SPA 通常采用组件化开发的方式,提高了代码的可维护性和可扩展性。
  • 服务器负载较低:由于只有初始页面加载时需要从服务器获取 HTMLCSSJavaScript 文件,减轻了服务器的负载。

缺点

  • 首次加载时间SPA 首次加载时需要下载较大的 JavaScript 文件,这可能导致初始加载时间较长。

  • SEO(搜索引擎优化)问题:由于 SPA 的内容是通过 JavaScript 动态生成的,搜索引擎的爬虫可能无法正确地获取和索引页面的内容。

  • 内存占用SPA 在用户浏览应用程序时保持单个页面的状态,这可能导致较高的内存占用。

  • 安全性:由于 SPA 通常使用 API 进行数据获取,因此需要特别注意安全性。

2、请简述您对vue的理解

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

vue是一个mvvm框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。

3、请简述vue的单向数据流

父级 prop 的更新会向下流动到子组件中,每次父组件发生更新,子组件 所有的 prop 都会刷新为最新的值

数据从父组件传递给子组件,只能单向绑定,子组件内部不能直接修改 父组件传递过来的数据,(可以使用 data 和 computed 解决)

4、Vue中组件怎么传值

父传子

  • props
  • $children
  • $refs

子传父

  • $emit
  • $parent

兄弟组件

  • provied
  • inject
  • eventBus
  • Vuex

5、MVVM的理解

MVVM是一种软件架构模式,MVVM 分为 ModelViewViewModel

  • Model代表数据模型,数据和业务逻辑都在Model层中定义;
  • View代表UI视图,负责数据的展示;
  • ViewModel负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作;

ModelView并无直接关联,而是通过ViewModel来进行联系的,ModelViewModel之间有着双向数据绑定的联系。因此当Model中的数据改变时会触发View层的刷新,View中由于用户交互操作而改变的数据也会在Model中同步

6、双向数据绑定原理,Vue是如何收集依赖

采用数据劫持结合发布者-订阅者模式的方式,data数据在初始化的时候,会实例化一个Observe类,在它会将data数据进行递归遍历,并通过Object.defineProperty方法,给每个值添加上一个getter和一个setter。在数据读取的时候会触发getter进行依赖(Watcher)收集,当数据改变时,会触发setter,对刚刚收集的依赖进行触发,并且更新watcher通知视图进行渲染。

依赖收集发生在defineReactive()方法中,在方法内new Dep()实例化一个Dep()实例,然后在getter中通过dep.depend()方法对数据依赖进行收集,然后在settter中通过dep.notify()通知更新。整个Dep其实就是一个观察者,吧收集的依赖存储起来,在需要的时候进行调用。在收集数据依赖的时候,会为数据创建一个Watcher,当数据发生改变通知每个Watcher,由Wathcer进行更新渲染。

7、vue2与vue3的区别

  • Vue2使用的是optionsAPI Vue3使用composition API,更好的组织代码,提高代码可维护性

  • Vue3使用Proxy代理实现了新的响应式系统,比Vue2有着更好的性能和更准确的数据变化追踪能力。

  • Vue3引入了Teleprot组件,可以将DOM元素渲染到DOM数的其他位置,用于创建模态框、弹出框等。

  • Vue3全局API名称发生了变化,同时新增了watchEffectHooks等功能

  • Vue3TypeScript的支持更加友好

  • Vue3核心库的依赖更少,减少打包体积

  • vue3支持更好的Tree Shanking,可以更加精确的按需要引入模块

8、Computed和Watch的区别

computed计算属性,通过对已有的属性值进行计算得到一个新值。它需要依赖于其他的数据,当数据发生变化时,computed会自动计算更新。computed属性值会被缓存,只有当依赖数据发生变化时才会重新计算,这样可以避免重复计算提高性能。

watch用于监听数据的变化,并在变化时执行一些操作。它可以监听单个数据或者数组,当数据发生变化时会执行对应的回调函数,和computed不同的是watch不会有缓存。

9、Vue组件中的data为什么是函数

Data 是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响。如果是引用类型(对象),当多个组件共用一个数据源时,一处数据改变,所有的组件数据都会改变,所以要利用函数通过 return 返回对象的拷贝,(返回一个新数据),让每个实例都有自己的作用域,相互不影响。

10、对Vue中keep-alive的理解

概念:keep-alive 是 vue 的内置组件,当它动态包裹组件时,会缓存不活动的组件实例,它自身不会渲染成一个 DOM 元素也不会出现在父组件链中

作用:在组件切换过程中将状态保留在内存中,防止重复渲染 DOM,减少加载时间以及性能消耗,提高用户体验。

生命周期函数:Activated 在 keep-alive 组件激活时调用,deactivated在 keep-alive 组件停用时调用

11、Vue循环的key作用

key的作用主要是为了高效的更新虚拟DOM,其原理是vuepatch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,减少DOM操作量,提高性能。

12、对虚拟DOM的理解

虚拟DOM就是用JS对象来表述DOM节点,是对真实DOM的一层抽象。可以通过一些列操作使这个棵树映射到真实DOM上。

如在Vue中,会把代码转换为虚拟DOM,在最终渲染到页面,在每次数据发生变化前,都会缓存一份虚拟DOM,通过diff算法来对比新旧虚拟DOM记录到一个对象中按需更新,最后创建真实DOM,从而提升页面渲染性能。

13、$nextTick原理及作用

Vue 的 nextTick 其本质是对 JavaScript 执行原理 EventLoop 的一种应用。 nextTick是将回调函数放到一个异步队列中,保证在异步更新DOM的watcher后面,从而获取到更新后的DOM。

因为在created()钩子函数中,页面的DOM还未渲染,这时候也没办法操作DOM,所以,此时如果想要操作DOM,必须将操作的代码放在nextTick()的回调函数中。

14、路由守卫

  • 全局前置钩子:beforeEachbeforeResolveafterEach
  • 路由独享守卫:beforeEnter
  • 组件内钩子:beforeRouterEnterbeforeRouterUpdatebeforeRouterLeave

15、Vue跨域的解决方案

跨域本质是浏览器基于同源策略的一种安全手段 所谓同源(即指在同一个域)具有以下三个相同点

  • 协议相同(protocol)
  • 主机相同(host)
  • 端口相同(port)

解决跨域的方法:JSONP、CORS、Proxy

CORS

CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应

CORS 实现起来非常方便,只需要增加一些 HTTP 头,让服务器能声明允许的访问来源

Proxy

代理(Proxy)也称网络代理,是一种特殊的网络服务,允许一个(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接。一些网关、路由器等网络设备具备网络代理功能。一般认为代理服务有利于保障网络终端的隐私或安全,防止攻击

方案一:如果是通过vue-cli脚手架工具搭建项目,我们可以通过webpack为我们起一个本地服务器作为请求的代理对象

方案二:通过服务端实现代理请求转发

方案三:通过配置nginx实现代理

16、Vue首屏加载慢的原因,怎么解决

首屏加载慢的原因:第一次加载页面有很多组件数据需要渲染

解决方法:

1.路由懒加载、异步组件、图片懒加载

2.ui 框架按需加载

3.gzip 压缩

17、Vue性能优化有哪些

编码阶段

  • v-ifv-for不一起使用
  • v-for保证key的唯一性
  • 使用keep-alive缓存组件
  • v-ifv-show酌情使用
  • 路由懒加载、异步组件
  • 图片懒加载
  • 节流防抖
  • 第三方模块按需引入
  • 服务端与渲染

打包优化

  • 压缩代码
  • 使用CDN加载第三方模块
  • 抽离公共文件

用户体验

  • 骨架屏
  • 客户端缓存

SEO优化

  • 预渲染
  • 服务端渲染
  • 合理使用 meta 标签

18、路由的hash和history模式的区别

hash模式 开发中默认的模式,地址栏URL后携带#,后面为路由。 原理是通过onhashchange()事件监听hash值变化,在页面hash值发生变化后,window就可以监听到事件改变,并按照规则加载相应的代码。hash值变化对应的URL都会被记录下来,这样就能实现浏览器历史页面前进后退。

history模式 history模式中URL没有#,这样相对hash模式更好看,但是需要后台配置支持。 原理是使用HTML5 history提供的pushStatereplaceState两个API,用于浏览器记录历史浏览栈,并且在修改URL时不会触发页面刷新和后台数据请求。

19、插槽

slot插槽,一般在封装组件的时候使用,在组件内不知道以那种形式来展示内容时,可以用slot来占据位置,最终展示形式由父组件以内容形式传递过来,主要分为三种:

  • 默认插槽:又名匿名插槽,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个匿名插槽。
  • 具名插槽:带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽。
  • 作用域插槽:默认插槽、具名插槽的一个变体,可以是匿名插槽,也可以是具名插槽,该插槽的不同点是在子组件渲染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件的传递过来的数据决定如何渲染该插槽。

实现原理:当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm.$slot中,默认插槽为vm.$slot.default,具名插槽为vm.$slot.xxx,xxx 为插槽名,当组件执行渲染函数时候,遇到slot标签,使用$slot中的内容进行替换,此时可以为插槽传递数据,若存在数据,则可称该插槽为作用域插槽。

20、vue3.0新特性

(1)重写双向数据绑定

vue2基于Object.defineProperty()实现;vue3 基于Proxy

(2)优化VDOM 在Vue2中,每次更新diff,都是全量对比,Vue3则只对比带有标记的,这样大大减少了非动态内容的对比消耗

(3)Vue3 Fragment

vue3允许我们支持多个根节点

(4)Vue3 Tree shaking

Vue3源码引入tree shaking特性,将全局 API 进行分块。如果你不使用其某些功能,它们将不会包含在你的基础包中。

在Vue2中,无论我们使用什么功能,它们最终都会出现在生产代码中。主要原因是Vue实例在项目中是单例的,捆绑程序无法检测到该对象的哪些属性在代码中被使用到

(5)Vue 3 Composition Api

Setup 语法糖式编程