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

校招前端vue面试题(并排更新)

时间:2023-03-31 18:19:47 vue.js

vue模板编译原理你知道吗,能简单介绍一下吗?简单的说,Vue的编译过程就是将模板转换成渲染函数的过程。它会经历以下几个阶段:生成AST树优化codegen首先解析模板,生成AST语法树(一种描述整个模板的JavaScript对象形式)。使用大量正则表达式解析模板,遇到标签和文本时,会执行相应的钩子进行相关处理。Vue的数据是响应式的,但并不是模板中的所有数据都是响应式的。有些数据在第一次渲染后不会发生变化,对应的DOM也不会发生变化。那么优化过程就是深度遍历AST树,根据相关条件标记树节点。我们可以跳过这些标记节点(静态节点)的比较,这在运行时极大地优化了模板。编译的最后一步是将优化后的AST树转换为可执行代码。模板和jsx有什么区别?对于运行时,只需要保证组件有render函数,预编译后只需要保证在构建过程中生成render函数即可。在webpack中,使用vue-loader编译.vue文件,内部依赖vue-template-compiler模块,在webpack构建过程中将模板预编译成render函数。和react类似,加入jsx语法糖解析器babel-plugin-transform-vue-jsx后,可以直接手写render函数。所以template和jsx都是渲染的一种形式。不同的是,JSX比template有更高的灵活性,在复杂的组件上更有优势,而template就显得有点迟钝了。但是template在代码结构上更符合视图和逻辑分离的习惯,更简单,更直观,也更好维护。简述mixin和extends的覆盖逻辑(1)mixin和extendsmixin和extends用于合并和扩展组件,两者都是通过mergeOptions方法进行合并。mixins接受一组mixin对象,其中mixin对象可以像普通实例对象一样包含实例选项,这些选项将合并到最终选项中。Mixin钩子按照传入的顺序被调用,并且在组件自己的钩子被调用之前被调用。extends主要是为了方便扩展单文件组件,接收一个对象或者构造函数。(2)mergeOptions执行过程规范化options(normalizeProps,normalizelnject,normalizeDirectives)判断未合并的options}if(child.mixins){for(leti=0,l=child.mixins.length;iast->renderfunctionvue会在模板编译版本的代码中执行compileToFunctionsconverttemplateintorenderfunction://compiletemplateintorenderfunctionconst{render,staticRenderFns}=compileToFunctions(template,options//omitted},this)CompileToFunctions中的主要逻辑如下:(1)调用parse方法将template转换为ast(抽象语法树)constast=parse(template.trim(),options)parse的目的:将tamplate转化为AST树,这是一种以JavaScript对象的形式描述整个模板的方式。解析过程:使用正则表达式顺序解析模板。在解析开始标签、结束标签和文本时,会分别执行相应的回调函数,从而达到构建AST树的目的。AST元素节点分为三种类型:类型1表示普通元素,类型2表示表达式,类型3表示纯文本(2)优化静态节点。做个标记,后续更新渲染可以直接跳过静态节点,优化AST的深度遍历,检查每个子树的节点元素是静态节点还是静态节点根。如果它们是静态节点,它们生成的DOM永远不会改变,这是对运行时模板更新的一个很好的优化。(3)生成代码constcode=generate(ast,options)generate将ast抽象语法树编译成renderstring并将static部分放入staticRenderFns,最后通过newFunction(`render`)生成render函数。行动和突变之间的区别。变异是同步更新。$watch在严格模式下会报错。动作是一个异步操作。您可以获取数据,然后调用mutation提交最终数据。详细答案参考前端进阶面试题。:先父后子,完成顺序:先子后父更新顺序:父更新导致子更新,子更新完成后销毁父子顺序:先父后子,完成顺序:先子后父原则双向数据绑定Vue.js采用数据劫持结合发布订阅者模式,通过Object.defineProperty()劫持各个属性的setter和getter,在数据变化时向订阅者发布消息,并触发相应的监听回调。主要分为以下几个步骤:递归遍历需要观察的数据对象,包括子属性对象的属性,添加setter和getter。给这个对象赋值会触发setter,然后就可以在监听到数据变化后,编译解析模板命令,用数据替换模板中的变量,然后初始化渲染页面视图,绑定每个对应的节点具有更新功能的命令,并添加一个监视数据的订阅者。一旦数据发生变化,接收到通知,更新视图Watcher订阅者是Observer和Compile之间的沟通桥梁。主要做的事情是:①在实例化自己的时候把自己加入到属性订阅者(dep)中②它必须有一个update()方法③当属性变化被dep.notice()通知时,可以调用自己的update()方法和触发Compile绑定的callback,然后就退休了。MVVM作为数据绑定的入口,集成了Observer、Compile和Watcher,通过Observer监听自身模型数据变化,通过Compile解析编译模板指令,最后使用Watcher搭建Observer和Compile之间的沟通桥梁,实现Data更改->查看更新;视图交互变化(输入)->数据模型变化的双向绑定效果。为什么v-for添加键?如果不使用key,Vue将使用最小化动态元素的算法,并尝试尽可能多地修改/重用相同类型的元素。key是vnode在Vue中的唯一标识。有了这个key,我们的diff操作就可以更准、更快、更准确:因为key没有原地复用,所以在sameNode函数中a.key===b.key比较时可以避免原地复用。所以它会更准确。更快:利用key的唯一性生成map对象获取对应节点,比遍历方式更快。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重新定义数据。虚拟DOM的原理是什么?虚拟DOM的实现原理主要包括以下三部分:利用JavaScript对象模拟真实DOM树,抽象真实DOM;diff算法——比较两个虚拟DOM树之间的差异;pach算法-将两个虚拟DOM对象之间的差异应用于真实的DOM树。Vue的基本原理当一个Vue实例被创建时,Vue会遍历数据中的属性,使用Object.defineProperty(vue3.0使用代理)将它们转换成getter/setter,并在内部跟踪相关的依赖关系,当属性是访问并在修改时通知更改。每个组件实例都有一个对应的watcher程序实例,在组件渲染过程中会将该属性记录为一个依赖,然后当依赖的setter被调用时,会通知watcher重新计算,从而导致其关联的组件被更新。vue轻量级框架优点:只关注视图层,是视图的集合来构建数据,大小只有几十kb;易学:中文开发,中文文档,无语言障碍,易懂易学;双向数据绑定:保留了angular的特点,数据操作更简单;组件化:保留了react的优点,实现了html的封装和复用,在构建单页应用方面具有独特的优势;视图、数据、结构分离:让数据更改更简单,不需要修改逻辑代码,只需要操作数据即可完成相关操作;virtualDOM:dom操作非常耗性能,不再使用原来的dom操作节点,大大解放了dom操作,但具体操作还是dom,只是换了一种方式;运行速度更快:与react相比,它还操作了virtualdom。在性能方面,vue有很大的优势。MVVM、MVC、MVP的区别MVC、MVP、MVVM是三种常见的软件架构设计模式,主要通过关注点分离来组织代码结构,优化开发效率。在开发单页应用时,往往一个路由页面对应一个脚本文件,所有的页面逻辑都在一个脚本文件中。页面的渲染、数据的获取、用户事件的响应所有的应用逻辑都混合在一起,这样在开发一个简单的项目时,你可能看不出有什么问题。如果项目变得复杂,整个文件就会变得冗长、混乱,这对项目的开发和后期的项目维护都是非常不利的。(1)MVCMVC通过分离Model、View和Controller来组织代码结构。其中View负责页面的展示逻辑,Model负责存储页面的业务数据并对相应的数据进行操作。而View和Model应用了Observer模式,当Model层发生变化时,会通知相关的View层更新页面。Controller层是View层和Model层之间的纽带。它主要负责用户和应用程序之间的响应操作。当用户与页面交互时,Controller中的事件触发器开始工作。通过调用Model层,完成Model。修改,然后Model层通知View层更新。(2)MVVMMVVM分为Model、View、ViewModel:Model代表数据模型,数据和业务逻辑定义在Model层;View代表UI视图,负责数据的展示;ViewModel负责监控Model中数据的变化并控制视图的更新,处理用户交互;Model和View没有直接关系,而是通过ViewModel连接起来的,Model和ViewModel之间存在双向数据绑定关系。因此,当Model中的数据发生变化时,会触发View层的刷新,View中因用户交互而发生变化的数据也会同步到Model中。这种模式实现了Model和View数据的自动同步,开发者只需要专注于数据的维护操作,而不需要自己去操作DOM。(3)MVPMVP模式与MVC的唯一区别在于Presenter和Controller。MVC模式中使用了观察者模式,实现了当Model层的数据发生变化时,View层的更新。这样View层和Model层就耦合在一起了。当项目逻辑变得复杂时,可能会造成代码混乱,可能会导致代码复用性出现一些问题。MVP模式通过使用Presenter实现了View层和Model层的解耦。MVC中的Controller只知道Model的接口,所以没有办法控制View层的更新。在MVP模式下,View层的接口是暴露给Presenter的,所以Model的变化和View的变化可以在Presenter中绑定在一起。这样就实现了View和Model的同步更新。这样就实现了View和Model的解耦,Presenter也包含了其他的响应逻辑。SSR的理解SSR也是服务端渲染,即在客户端将Vue渲染标签成HTML的工作在服务端完成,然后HTML直接返回给客户端。SSR的优点:更好的SEO首屏SSR的加载速度更快的缺点:开发条件会受限,服务端渲染只支持beforeCreate和created两个hook;当需要一些外部扩展库时需要特殊处理,服务端渲染应用也需要运行在Node.js环境中;更多的服务器端负载。你对你的Vue项目做了哪些优化?(1)代码层面的优化v-if和v-show区分使用场景与computed和watch场景v-for遍历必须给item添加key,避免同时使用v-if长列表性能优化事件破坏图片资源lazy加载路由第三方插件的延迟加载按需引入无限列表性能优化服务端渲染SSR或预渲染(二)Webpack层面的优化Webpack对图片进行压缩,减少冗余代码,从ES6到ES5提取常用代码模板预编译提取ComponentCSS优化SourceMap构建结果输出分析Vue项目编译优化(三)基础web技术优化启用gzip压缩浏览器缓存CDN使用ChromePerformance寻找性能瓶颈Vue3.x响应式数据原理Vue3.x使用相反,Proxy替换了Object.defineProperty。因为Proxy可以直接监听对象和数组的变化,拦截方式多达13种。并且作为新标准,浏览器制造商将专注于持续的性能优化。proxy的基本用法//proxy默认只会代理一级对象,只有当value又是一个对象时才重新代理,而不是一上来就代理,以提高性能。不像vue2.x递归遍历每个对象属性lethandler={set(target,key,value){returnReflect.set(target,key,value);},get(target,key){if(typeoftarget[key]=='object'&&target[key]!==null){returnnewProxy(target[key],handler);//惰性代理,只有当值再次为对象时,才再次代理以提高性能}returnReflect.get(target,key);}}letobj={school:{name:'poetry',age:20}};letproxy=newProxy(obj,handler);//返回对象的代理proxy.schoolv-model的原理?在vue项目中,我们主要使用v-model指令对forminput、textarea、select等元素创建双向数据绑定。我们知道v-model本质上只是语法糖,v-model内部针对不同的input元素使用不同的属性并抛出不同的事件:text和textarea元素使用value属性和input事件;checkbox和radio使用checked属性和change事件;select字段使用value作为prop并将change作为event。以输入表单元素为例:等同于在定义组件中,v-model默认会使用名为value的prop和名为input的事件,如下所示:父组件:子组件:

{{value}}
props:{value:String},methods:{test1(){this.$emit('input','小红')},},Vue性能优化编码优化:事件代理keep-alive拆分组件key,保证路由唯一延迟加载,异步组件防抖节流Vue加载性能优化第三方模块按需导入(babel-plugin-component)图片延迟加载用户体验app-skeleton骨架屏shellappshellpwaSEO优化pre-渲染