vue响应式原理和vue2和vue3原理的区别

这道题问道的频率极高,就我经历的多场面试几乎都会问到,而且是面试到vue方面的开门题。

  1. vue2是根据Object.definepropretyApi来对数据进行劫持,并结合订阅-发布设计模式来实现的。vue3是用proxy代理对象来实现的。
  2. Object.defineproprety只能代理属性,而proxy能代理对象。
  3. 对象新增属性proxy代理可以监听到,Object.defineproprety监听不到。
  4. Object.defineproprety的代理行为是在破坏原对象的基础上实现的,proxy代理则不会破坏原对象,只是在原对象上覆盖了一层。
  5. 数组新增proxy代理可以监听到,Object.defineproprety监听不到。
  6. proxy代理不兼容IE11及以下。

vue中的nextTick是干什么用的?

在vue中修改响应式数据后并不会马上出发dom更新,而是把需要更新的watcher加入quequeWacher队列中。如果我们需要在数据更新后马上获取到变化后的dom就需要在nextTick函数中进行获取到变化后的dom。

nextTick原理

是借助浏览器的事件循环来完成的,因为每次事件循环之间都有一次视图渲染,nextTick使用promise来实现的,当浏览器不支持promise时就会降级使用setImmediate,setTimeout来实现。

vue2和vue3的区别

  1. vue2是选项式API,vue3是组合式API。选项式API各个方法是分散的,组合式API是根据功能进行自由组合的,可以讲data,methods,compute等按照功能划分放在一起。
  2. vue2是讲响应式数据放在data里的,vue3是通过ref或者reactive讲数据声明为响应式的。
  3. vue2响应式数据是通过Object.defineproprety劫持数据来实现的,vue3是通过Proxy代理来实现的。
  4. vue3将生命周期中beforeCreatecreated合并到setup函数中。
  5. vue3可以有多个根节点,vue2只能有一个。
  6. vue3新增了传送组件Teleport和异步依赖处理组件Suspense。

什么是虚拟dom

就是描述dom结构的js对象

为什么要用虚拟dom

  1. 原生dom渲染开销很大。
  2. 虚拟dom就是为了减少原生dom渲染的次数,通过diff算法找到差异部分来渲染到dom上。

说一下diff算法

diff算法本质上是找出两个对象之间的差异,目的是尽可能复用节点,在vue中状态发生改变时用来计算改变前的虚拟dom和改变后的虚拟dom之间的差异的算法。

简述vuex

面试问到这个问题的时候,不要上来就开始说什么state,mutation...。你要先阐述Vuex干嘛用的,什么时候需要用Vuex。

  1. vuex是全局状态管理器,可以管理应用内所有组件的状态,并不是每个项目都需要引入vuex,只有当这些页面共享着多个数据的状态时才应该引入vuex。
  2. vuex有三个核心概念,state,mutations,actions,其中,state是存放数据的地方,mutations中的函数则是用来修改state数据的,也只能用来修改state数据,并且不能执行异步操作。actions是用来处理异步操作的,比如发送异步请求,然后调用mutation中的函数来修改state
  3. vuex还有两个概念,getters,modulesgetters类似计算属性中的computed一样用来描述依赖响应式数据变化的复杂逻辑处理。modules则是用分割仓库为模块的,便于项目的维护管理,每个module都有自己的,state,mutations,actions

简述pinia

pinia其实就是vuex5,和vuex4的区别主要是

  1. pinia使用更简单,更符合开发者习惯。
  2. pinia中没有mutations,状态state可以直接修改,或者在actions中修改,或者使用它的$patch方法修改。
  3. pinia中没有modules,如果想有多个store,直接使用defineStore定义多个store传入不同的id即可。
  4. 更好的TS支持。

vue-router是什么,描述一下它的原理?

vue-router是vue官方的路由管理器,有hash和history两种模式

hash

就是通过监听hashchange事件来实现更新页面部分内容的操作,url后面会带有#号。

history

通过监听popstate事件来实现更新页面部分内容的操作,原理和hash模式一样,只是url后不会有#号,点哪个url就用url替换掉浏览器当前显示的url。

说一下路由守卫?

路由守卫通俗理解就是一种中间件用于路由跳转时处理一些特殊操作,例如,登录验证,权限验证等。

路由守卫分为三种,全局守卫,路由独享守卫,组件路由守卫

全局守卫

  1. beforeEach,接收三个参数,to,from,next,每个路由跳转前都会触发,一般用于登录验证比较多。
  2. beforeResolve, 和beforeEach类似,区别是在导航确认前,同时在所有组件内守卫和异步路由组件被解析之后调用。
  3. afterEach,在路由完成跳转后调用,接收,to,from两个参数。

路由独享守卫

beforeEnter,一般配置在路由配置文件中(router/index.js),对进入某个路由之前进行相关操作。

组件路由守卫

统一接收to,from,next三个参数

  1. beforeRouteEnter,在进入路由之前调用,无法获取到vue实例。
  2. beforeRouteUpdate,在当前路由改变,但是该组件被复用时调用。
  3. beforeRouteLeave,在离开组件时调用。

跨域的解决方案

  1. 前端配置开发时的代理转发规则用于开发期间解决跨域问题
  2. 服务端配置nginx端口转发解决跨域,这是比较通用的方案,开发和部署都可。
  3. 可以将打包后的静态文件放到后端可访问文件目录,同源了就没有跨域问题了,但这只能用于部署。
  4. 服务端配置跨域策略,放行浏览器发送的options请求。