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

多问多查的vue面试题千万不要错过,检查是否有任何问题被问到!

时间:2023-03-31 18:37:08 vue.js

生命周期钩子函数Vue实例有一个完整的生命周期,即从创建、初始化数据、编译模板、挂载Dom->渲染、更新->渲染、卸载等一系列过程,我们称之为Vue的生命周期Vue中组件生命周期调用顺序生命周期说明beforeCreate创建组件实例时,创建的组件实例在组件的属性生效之前已经完全创建,属性也绑定了,但是真正的dom还没有已生成,$el尚不可用。使用beforeMount在挂载开始前调用:第一次调用相关的render函数,mounteddel被新创建的vm.$el替换,挂载到实例后调用这个hook。补丁前更新组件数据更新后,activatedkeep-alive独占。当组件被激活时,它被称为deadactivatedkeep-alive。当组件被销毁时,它会调用beforeDestory。在组件销毁之前,它会调用destoryed。DOM的体积非常大,单个div中的dom属性多达294个;VirtualDOM使用一个原生的JS对象来描述一个DOM节点,因此它比创建一个DOM便宜很多。VNode是对真实DOM的抽象描述。它的核心定义无非是几个关键的属性,比如标签名、数据、子节点、键值等,其他属性用来扩展VNode的灵活性,实现一些特殊的功能。由于VNode只是用来映射到真实的DOM上进行渲染,不需要包含操作DOM的方法,所以非常轻量简单。VirtualDOMtorealDOM需要经过以下过程:VNode的create,diff,patchv-model双向数据绑定原理Vue双向数据绑定是通过数据劫持结合发布订阅模式实现的,也就是说,数据和视图同步,数据改变,视图随之改变,视图改变,数据也随之改变;核心:Object.defineProperty()方法。v-model本质上是语法糖,v-model内部对不同的input元素使用不同的属性并抛出不同的事件asevent复制代码Computed和watchvueslots的区别自身组件内部设置的slots就像一个盒子,位置由子组件决定,内容由父组件决定。实现了内容分发,提高了组件定制化程度,组件变得更加灵活。Defaultslot:不需要name属性,子组件腹中的第一个元素节点作为defaultslot。

子页面

hello,world!

子页面

hello,world!

复制代码namedslot:用于多个slot的情况,使用name来标识slot。

子页面

>divclass="parent-page">

head

foot

body

子页面

Head

Body

Foot

复制代码Scopeslot:子组件通过数据到父组件。

子页面

head:{{slotProps.data}}

子页面

Header:datafromchild-component.

复制代码Vue、Angular和React有什么区别?Vue和AngularJS的区别Angular是用TypeScript开发的,Vue可以用javascript也可以用TypeScript。AngularJS依赖于对数据的脏检查,所以Watcher越多越慢;Vue.js使用基于依赖跟踪的观察,使用异步队列更新,所有的数据都是独立触发的。AngularJS社区完备,Vue学习成本小。Vue和React的区别。Vue组件分为全局注册和本地注册。在React中,导入相应的组件,然后在模板中引用;props可以动态改变,子组件也可以改变。实时更新。在react中,官方建议props像纯函数一样,输入输出一致,不建议通过props改变view;子组件一般需要显式调用props选项来声明它期望获取的数据。在react中不是必须的,另外两个有props验证机制;每个Vue实例都实现了一个事件接口,以方便父子组件之间的通信。小项目不需要引入状态管理机制,react必须自己实现;vue使用Slots分发内容,使得父组件的内容可以和子组件的模板混合;Vue拥有更多的指令系统,让模板实现更丰??富的功能,而React只能使用JSX语法;Vue增加了语法糖computed和watch,但是在React中,需要自己写一套逻辑来实现;react的思想都是在js中,通过js生成html,所以设计了jsx,通过js操作css,styled-component,社区的jss等;而vue将html、css、js结合在一起,使用了自己的处理方式。Vue有一个单文件组件,可以把html、css、js写到一个文件中,html提供模板引擎进行处理。React做的事情很少,很多都交给了社区。vue里面很多东西都是内置的,写起来真的很方便。比如redux的combineReducer对应vuex的modules,reselect对应vuex和vue组件的getter。computed,vuex的mutation是直接改变的原始数据,redux的reducer返回一个全新的状态,所以redux结合immutable来优化性能,vue不需要。React的整体思想是函数式的,因此提倡纯组件、数据不可变、单向数据流。当然,也可以在需要双向的地方进行。比如结合redux-form,组件的横向拆分一般是通过高层组件。而vue是数据变量,双向绑定,声明式写法,vue组件水平拆分。在很多情况下,使用mixin$route和$router之间的区别。$route是一个路由信息对象,包括path、params、hash、query、fullPath、matched、name等路由信息参数。而$router是路由实例对象,包括路由跳转方法、钩子函数等。如何优化Vue的SPA的加载速度,减少入口文件的体积?为本地缓存启用Gzip压缩。使用SSR,优化nuxt.jsvue项目中的编码阶段。不要在模板中写太多的表达式。将data中的数据最小化,data中的数据会添加getters和setters,并收集相应的watchers。v-if和v-for不能一起使用。如果需要使用v-for将事件绑定到每个元素,请使用事件代理SPA页面。使用keep-alive缓存组件频繁切换。使用v-show,不频繁切换,调用子组件时使用v-if循环添加key,保证key唯一使用路由懒加载,异步组件防抖,节流第三方模块按需导入长列表滚动到可见区域动态加载图片LazilyLoadingSEO优化预渲染服务端渲染SSR、nuxt.js打包优化压缩代码TreeShaking/ScopeHoisting利用CDN加载第三方模块多线程打包happypacksplitChunks提取公用filessourceMap优化用户体验骨架屏PWA渐进式web应用,多用A技术增强webapp的功能,让web应用呈现出与原生应用相似的体验。还可以使用缓存(客户端缓存,服务端缓存)优化,在服务端启用gzip压缩等。Vue有数据响应性,为什么还需要diff?核心原因:GranularReact通过setState知道发生了变化,但是不知道变化在哪里,所以需要通过diff找到变化的地方,更新dom。Vue已经可以通过响应式系统知道哪里发生了变化,但是所有的变化都会通过响应式系统创建大量的Watcher,非常耗性能,所以Vue的使用方式是通过响应式来知道是哪个组件发生了变化system,然后在组件内部使用diff。这样的中粒度策略既不会产生大量的Watcher,又能减少diff节点的数量,一举两得。Vue模板编译编译的核心是将template模板编译成render函数,主要分为以下三个步骤:在MVC中进入ViewModel。Model层代表数据模型,View代表UI组件,ViewModel是View层和Model层之间的桥梁。数据将绑定到viewModel层并自动将数据呈现到页面。当视图发生变化时,会通知viewModel层更新数据。响应式数据原理(Vue2.x&Vue3.0)Vue2.x初始化数据时,会使用Object.defineProperty重新定义数据中的所有属性。当页面使用到相应的属性时,会先收集依赖(收集当前组件watcher),如果属性发生变化,会通知相关依赖进行更精细的分发(发布-订阅模式)。Vue3.0使用es6中的proxy代替Object.defineProperty进行数据监控。Proxy和Object.defineProperty的优缺点?Proxy的优点如下:Proxy可以直接监控对象而不是属性。Proxy可以直接监听数组的变化。Proxy有多达13种拦截方法,不限于apply、ownKeys、deleteProperty、has等。Object.defineProperty没有的Proxy返回一个新的对象。我们只能操作new对象来达到目的,而Object.defineProperty只能遍历对象属性,直接修改Proxy。作为新标准,浏览器制造商将专注于持续的性能优化,也就是传说中的新标准的绩效奖金。Object.defineProperty的优点如下:兼容性好,支持IE9vue的$nextTick在下一次DOM更新周期结束后执行延迟回调。nextTick主要使用宏任务和微任务。根据执行环境尝试使用PromiseMutationObserversetImmediate。如果以上都不起作用,请使用setTimeout定义一个异步方法。多次调用nextTick会将方法存入队列,通过这个异步方法清空当前队列。为什么Vue组件中的数据一定是函数复用组件?将返回一个新的数据,这意味着每个组件实例都有自己的私有数据空间,不会共享同一个数据对象。vue中组件通信的方式是fathertoson:propssontofather:$emit,refbrother:EventBusvue-routervue-router是vue的官方插件,主要用来管理前端路由。对于Vue这样的渐进式前端开发框架,为了构建SPA(单页面应用),需要引入前端路由系统,这就是Vue-Router的意思。前端路由的核心是在改变视图的同时不向后端发送请求。作用是:改变URL,阻止浏览器向服务器发送请求。检测URL的变化。记录当前页面的状态。您可以使用浏览器的前进和后退功能。URL路径决定了页面如何显示历史和哈希模式之间的差异。history模式是浏览器本身的特性,Vue-Router正是利用这两个特性(通过调用浏览器提供的接口)来实现前端路由。2.比较表差异\modehashhistory监听事件hashChangepopstate缺点#数不好看子路由刷新404,ie9及以下不兼容推送操作window.location.assignwindow.history.pushStatereplace操作window.location.replacewindow.history.replaceState访问操作窗口。history.gowindow.history.go后向操作window.history.go(-1)window.history.go(-1)正向操作window.history.go(1)window.history.go(1)3.关于popstate事件监听路由的局限性history对象的back()、forward()和go()操作会主动触发popstate事件,但pushState和replaceState不会触发popstate事件。这时候我们就需要手动触发页面跳转(渲染)。4.子路由刷新history模式子路由刷新会404的解决方法,所以需要后端配合,默认将不匹配的路由指向html文件5.浏览器(环境)兼容处理历史模式下的pushState和replaceState是HTML5IE9的新特性将强制降级为使用散列模式,非浏览器环境转为抽象模式。6.router-linkrouter-linkclick相当于调用$router.push方法修改url优于硬编码的,原因如下:无论是HTML5的history模式还是hash模式,其行为都是一致的,所以当你想切换路由模式,或者在IE9中降级使用hash模式时,不需要做任何改变。在HTML5history模式下,router-link会保护点击事件,使浏览器不会重新加载页面。在HTML5history模式下使用base选项时,所有to属性都不需要写(basepath)。vue-router路由的懒加载是和vue一样的单页应用。如果没有路由的懒加载,用webpack打包出来的文件会很大,导致进入首页需要加载的内容太多,出现长时间的白屏,使用路由懒加载可以分页面,需要的时候加载页面,可以有效的分担首页的加载压力,减少首页的加载时间。懒加载vue路由的三种方式:vue异步组件ES6的import()webpack的require.ensure()1。vue异步组件该方法主要使用resolve的异步机制,使用require代替import实现按需加载exportdefaultnewRouter({routes:[{path:'/home',',component:(resolve)=>require(['@/components/home'],resolve),},{路径:'/about',',component:(resolve)=>require(['@/components/about'],resolve),},],})复制代码2.ES6import()vue-router提供了一个方法,可以理解为也是通过Promise的resolve机制。因为Promise函数返回的Promise就是resolve组件本身,我们可以使用import来导入组件。exportdefaultnewRouter({routes:[{path:'/home',component:()=>import('@/components/home'),},{path:'/about',component:()=>import('@/components/home'),},],})复制代码1.webpack的require.ensure()这种模式可以通过参数中的webpackChunkName来单独打包js。exportdefaultnewRouter({routes:[{path:'/home',component:(resolve)=>require.ensure([],()=>resolve(require('@/components/home')),'home'),},{路径:'/about',component:(resolve)=>require.ensure([],()=>resolve(require('@/components/about')),'about'),},],})文案篇幅有限,没发出来的题都在前端面试题里。需要完整PDF资料的朋友只需点击这里免费获取!被问到问题的朋友可以在评论区说说你是怎么回答的。如果没被问到,多看书背,说不定会遇到~这篇文章对你有帮助,欢迎评论点赞支持一波,谢谢!