当前位置: 首页 > Web前端 > vue.js

vue面试题+答案,2022前端面试

时间:2023-03-31 20:42:37 vue.js

vue面试题+答案,2022前端面试面试题视频讲解(高效学习):进入了解MVC和MVVM的区别MVCMVC全称ModelViewController,也就是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计模型模型(model):它是应用程序中用来处理应用数据逻辑的部分。通常模型对象负责访问数据库中的数据View(视图):应用程序中处理数据显示的部分。通常视图是从模型数据创建的控制器(controller):它是处理用户交互的应用程序的一部分。通常controller负责从view中读取数据,控制用户输入,将数据发送给modelMVC思想:一句话描述就是controller负责用view显示model的数据,换句话说就是赋值控制器中模型的数据给视图。MVVMMMVVM添加了一个类似VM的ViewModel层:做了两件事来实现数据的双向绑定。一种是将[Model]转换为[View],即把后端传过来的数据转换成你看到的页面。实现的方式是:数据绑定。二是将[view]转化为[model],即将浏览的页面转化为后台数据。实现方式是:DOM事件监听。MVVM与MVC最大的区别在于它实现了View和Model的自动同步,即当Model的属性发生变化时,我们不需要手动操作Dom元素来改变View的显示,而是改变property来对应View层显示会自动变化(对应Vue的数据驱动思想)。从整体上看,MVVM比MVC精简了很多。不仅简化了业务和接口的依赖,还解决了数据更新频繁的问题,不再需要使用选择器来操作DOM元素。.因为在MVVM中,View并不知道Model的存在,Model和ViewModel无法观察到View。这种低耦合模式提高了代码的可重用性。注意:Vue并不完全遵循MVVM的思想。官方网站本身也解释了这个问题。为什么官方说Vue没有完全遵循MVVM思想呢?严格的MVVM要求View不能直接和Model通信,而Vue提供了属性$refs让Model直接操作View,违反了这个规则,所以Vue并没有完全遵循MVVM。Vue是如何实现响应式数据的?(响应式数据原理)Vue2:Object.defineProperty重新定义了data中的所有属性。Object.defineProperty可以对数据的获取和设置添加拦截功能,拦截属性获取,收集依赖。拦截属性的更新操作并通知它。具体过程:首先Vue使用initData初始化用户传入的参数,然后使用newObserver观察数据。如果数据是对象类型,会调用this.walk(value)处理对象,内部使用defineeReactive循环对象属性定义响应式变化的核心是使用Object.defineProperty重新定义数据。那么vue是如何检测数组变化的呢?数组就是使用object.defineProperty重新定义数组的每一项。我们都知道可以引起数组变化的方法,如pop、push、shift、unshift、splice、sort、reverse。只要执行这些方法,改变数组的内容,我只是更新内容,好理解吗?用于函数劫持,重写数组方法。具体来说,就是改变数组的原型,改成自己的。当用户调用数组的一些方法时,使用自己的方法,然后通知视图进行更新。数组中的每一项都可能是一个对象,所以我会观察数组中的每一项(并且只能观察到数组中的对象,已经观察到的不会观察到)vue3:改用proxy,就可以直接监听对象数组的变化。vue轻量级框架优点:只关注视图层,是视图的集合来构建数据,大小只有几十kb;易学:中文开发,中文文档,无语言障碍,易懂易学;双向数据绑定:保留了angular的特点,数据操作更简单;组件化:保留了react的优点,实现了html的封装和复用,在构建单页应用方面具有独特的优势;视图、数据、结构分离:让数据更改更简单,不需要修改逻辑代码,只需要操作数据即可完成相关操作;virtualDOM:dom操作非常耗性能,不再使用原来的dom操作节点,大大解放了dom操作,但具体操作还是dom,只是换了一种方式;运行速度更快:与react相比,它还操作了virtualdom。在性能方面,vue有很大的优势。为什么data必须是vue组件中的一个函数?该对象是引用类型。组件复用时,由于数据对象都指向同一个数据对象,当一个组件中的数据被修改时,其他复用组件中的数据也会同时被修改;而使用返回对象的函数,由于每次都返回一个新的对象(Object的实例),引用地址不同,所以不会出现这个问题。v-if和v-show的区别v-if在编译的时候会被转换成三元表达式,不满足条件的时候不会渲染这个节点。v-show会被编译成指令,当不满足条件时,控件样式会隐藏对应的节点(display:none)为什么Vue要使用异步渲染?Vue是一个组件级别的更新。如果不使用异步更新,则每次更新数据时都会重新渲染当前组件。因此,为了性能,Vue会在本轮数据更新后异步更新视图。核心思想nextTick。dep.notify()通知watcher更新,subs[i].update依次调用watcher的update,queueWatcher将watcher放回队列,nextTick(flushSchedulerQueue)在下一个tick刷新watcher队列(异步)。父子组件生命周期调用顺序(简单)渲染顺序:先父后子,完成顺序:先子后父更新顺序:父更新导致子更新,子更新完成后父销毁顺序:先父,thenchild,completionorder:firstchild和parent使用VNode来描述一个DOM结构。一个虚拟节点就是用一个对象来描述一个真实的DOM元素。首先将template(realDOM)转化为ast,ast树通过codegen生成render函数,render函数中的_c方法将其转化为virtualdomdiff算法时间复杂度:一棵树的完整diff算法为一个O(n*3)的时间复杂度,vue优化后转化为O(n)。理解:最小更新,key很重要。这可以是这个节点的唯一标识符,告诉diff算法它们在变化前后是同一个DOM节点。为什么扩展名v-for有一个键?如果没有key,就会被暴力复用。比如只说一个比如移动一个节点或者添加一个节点(ModifytheDOM),添加一个key只会移动和减少对DOM的操作。只有相同的虚拟节点才会进行精细比较,否则,旧的会被暴力删除,新的会被插入。只进行同层比较,不进行跨层比较。diff算法的优化策略:四种hitlookups,四种指针先旧后新(开始后插入删除节点的情况)和旧后新后(插入或删除节点的情况)beforeend)oldfrontandnewback(headandtailratio,这个发生了,涉及移动节点,然后新front指向的节点,移动到oldback之后)oldbackandnewfront(tailandheadratio),这就发生了,涉及到移动节点,然后新前面指向的节点,移动到旧前面)为什么v-for要加一个key呢?如果你不使用键,Vue将使用一种方法来最小化动态元素,并尝试尽可能多地修改/重用相同类型元素的算法。key是vnode在Vue中的唯一标识。有了这个key,我们的diff操作就可以更准、更快、更准确:因为key没有原地复用,所以在sameNode函数中a.key===b.key比较时可以避免原地复用。所以它会更准确。更快:利用key的唯一性生成map对象获取对应节点,比遍历方式更快。vue-router路由钩子函数的执行顺序是怎样的?路由钩子的执行过程是怎样的?钩子函数的类型有:全局守卫、路由守卫、组件守卫完整的导航解析过程:导航被触发。在停用的组件中调用beforeRouteLeave守卫。调用全局beforeEach守卫。在可重用组件中调用beforeRouteUpdate守卫(2.2+)。在路由配置中调用beforeEnter。解析异步路由组件。在激活的组件中调用beforeRouteEnter。调用全局beforeResolve守卫(2.5+)。导航已确认。调用全局afterEach挂钩。触发DOM更新。在beforeRouteEnter守卫中调用传递给next的回调函数,创建的组件实例会作为回调函数的参数传入。说说我个人对vuex的理解。Vuex是专门为vue提供的全局状态管理系统,用于多个组件中的数据共享和数据缓存。(不能持久化,内部核心原理是创建一个全局实例newVue)主要包括以下几个模块:State:定义了应用状态的数据结构,这里可以设置默认的初始状态。Getter:允许组件从Store中获取数据。mapGetters辅助函数只是将存储中的getter映射到本地计算属性。Mutation:是改变store中状态的唯一方法,并且必须是一个同步函数。动作:它用于提交突变而不是直接改变状态,并且可以包含任何异步操作。Module:允许将单个Store拆分为多个store,同时存储在单个statetree中。keep-alive使用场景及原理keep-alive是Vue内置的一个组件,可以实现组件缓存,在组件切换时不会卸载当前组件。两个常用的属性include/exclude允许有条件地缓存组件。activated/deactivated两个生命周期用于了解当前组件是否处于活动状态。keep-alive中也使用了LRU(leastrecentlyused)算法,选择最长时间没有被使用的组件进行淘汰。官方对Vue.extend的作用和原理的解释:Vue.extend使用基本的Vue构造函数来创建一个“子类”。参数是一个包含组件选项的对象。其实就是一个子类构造器,是Vue组件的核心API。实现的思路是使用原型继承的方法返回Vue的子类,使用mergeOptions合并传入组件的选项和父类的选项。Vue组件如何通信?Vue组件通信方式如下:props/$emit+v-on:数据通过props自上而下传递,信息通过$emit和v-on向上传递。EventBus:通过EventBus发布和订阅信息vuex:是一个全局的数据管理库,可以通过vuex管理全局的数据流$attrs/$listeners:Vue2.4中新增的$attrs/$listeners可以进行跨级组件communicationprovide/inject:让一个祖先组件向它的所有子孙组件注入一个依赖,无论组件层级有多深,它总是在上下游关系建立时生效,成为跨组件的基础componentcommunicationandhavesomeusefulsoltslotsorrefinstancescommunicate,使用场景太有限就不细说了。computed和watch有什么区别?Computed:computed是计算属性,即计算值。它更多用于计算计算值的场景。计算是可缓存的。计算值在getters执行后缓存起来,只有当依赖的属性值改变后,下次才会再次调用相应的getter来计算计算值。Computed适用于比较消耗性能的计算场景。watch:更多的是“观察”的作用,类似于一些数据的监听Callback,用来观察props$emit或者这个组件的值。当数据发生变化时,回调执行后续操作,不缓存。当页面被重新渲染时,这个值不会改变,它会被执行。总结:当我们要进行数值计算时,依赖于其他数据,将这个数据设计为计算出来的。如果需要在某个数据变化的时候做点什么,用watch观察这个数据变化的优劣虚拟DOM?优点:保证性能下限:VirtualDOM可以通过diff找到最小差异,然后批量patch。这种操作虽然不如手动优化,但比粗略的DOM操作性能要好很多,所以虚拟DOM可以在不手动操作DOM的情况下保证性能的下限:虚拟DOM的diff和patch都在Automaticallyinoneupdate,我们不需要手动操作DOM,大大提高了开发效率跨平台:虚拟DOM本质上是一个JavaScript对象,DOM与平台强相关,如服务端渲染、移动开发等。缺点:无法进行极致优化:在一些对性能要求极高的应用中,无法针对虚拟DOM进行极致优化。比如VScode使用直接手动操作DOM来进行极致的性能优化。虚拟DOM实现原理?虚拟DOM本质上是一个JavaScript对象。当真实DOM的抽象状态发生变化时,记录新树和旧树的差异,最后将差异更新到真实dom中。Vue初始化页面闪动问题如何解决?出现这个问题是因为在vue代码解析之前,无法控制页面中DOM的显示,所以会看到模板字符串等代码。解决方法是在css代码中加入v-cloak规则,在需要编译的标签中加入v-cloak属性:[v-cloak]{display:none;}{{message}}

Vue-router路由有哪些模式?一般有两种模式:(1)**hash模式**:对于hash值的后续变化,浏览器既不会向服务器发送请求,也不会刷新浏览器,hash值的每一次变化都会触发一次哈希更改事件。(2)**历史模式**:利用HTML5中新的pushState()和replaceState()方法。这两个方法应用于浏览器的历史堆栈。在已有的back、forward、go的基础上,提供了修改历史的功能。只是当他们进行修改的时候,虽然改变了当前的URL,但是浏览器并不会立即向后端发送请求。$nextTick是什么?Vue对响应式的实现不会在数据发生后立即更新DOM。使用vm.$nextTick是在下一个DOM更新周期结束后立即执行延迟回调。修改数据后使用,可以在回调中获取更新后的DOM。Vue中的computed和watch有什么区别?计算属性computed:(1)**支持缓存**,只有当依赖的数据发生变化时,才会重新执行计算函数;(2)计算属性中**不支持异步操作**;(3)计算属性的函数它们都有一个get**(默认,获取计算属性)**和set**(手动添加,设置计算属性)方法;(4)计算属性是自动监听依赖值的变化,从而动态返回内容。监听属性watch:(1)**不支持缓存**,只要数据发生变化,就会执行监听函数;(2)监听属性中**支持异步操作**;(3)Listening属性的Value**可以是一个对象,接收handlercallback,deep,immediate三个属性**;(3)Listening是一个过程,当监听值发生变化时,可以触发回调并**做一些其他的事情**。行动和突变之间的区别。变异是同步更新。$watch在严格模式下会报错。动作是一个异步操作。获取数据后可以调用mutation提交最终数据。谈谈对keep-alive的理解。keep-alive可以实现组件缓存。切换时不会卸载当前组件。两个常用的属性include/exclude,两个生命周期activated,deactivatedVue模板编译原理Vue编译过程就是将模板转化为render函数。该过程分为以下三个步骤。第一步是将模板字符串转换成elementASTs(Parser)第二步是在AST上标记静态节点,主要用于虚拟DOM渲染优化(optimizer)第三步是使用elementASTs生成render函数代码字符串(代码生成器)Vue修饰符有哪些?事件修饰符.stop阻止事件继续传播。prevent阻止标签的默认行为。capture采用事件捕获方式,即元素自身触发的事件先在这里处理,再由元素内部处理。self仅当在event.target当前元素本身时触发处理函数。once事件只会被触发一次。被动告诉浏览器你不想阻止事件的默认行为。v-model修饰符。lazy通过这个修饰符,转化为在change事件中重新同步。number自动将用户输入的值转换为数值类型。trim自动过滤用户输入的第一个和最后一个空格键盘事件的修饰符。enter.tab.delete(捕获“delete”和“backspace”键).esc.space...shakeThrottlingVue加载性能优化第三方模块按需导入(babel-plugin-component)图片延迟加载用户体验app-skeleton骨架屏shellappshellpwaSEO优化预渲染