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

合格的vue开发者应该知道的面试题

时间:2023-04-01 01:21:54 vue.js

Vue子组件和父组件执行顺序加载渲染过程:父组件beforeUpdate子组件beforeUpdate子组件updated父组件updated销毁过程:父组件beforeDestroy子组件beforeDestroy子组件销毁父组件销毁vue-cli项目中构建了哪些技术,它们的功能是什么vue.js:vue-cli的核心项目,主要特点是双向数据绑定和组件系统。vue-router:vue官方推荐的路由框架。vuex:专门为Vue.js应用项目开发的状态管理器,主要用来维护vue组件之间共享的一些变量和方法。axios(或fetch、ajax):用于发起GET或POST等http请求,基于Promise设计。Vuex等:专为Vue设计的移动端UI组件库。创建一个emit.js文件,用于vue事件机制的管理。webpack:模块加载和vue-cli项目打包器。vue如何监控一个对象或者一个数组的某个属性的变化?当你直接在项目中设置数组的某一项的值,或者直接设置对象的某个属性的值时,这时候你会发现页面没有更新。这是因为Object.defineProperty()的限制,它不能监视变化。解决方法:this.$set(你要改变的数组/对象,你要改变的位置/键,你要改变成什么值)this.$set(this.arr,0,"OBKoro1");//改变数组this.$set(this.obj,"c","OBKoro1");//改变对象调用以下数组的方法splice(),push(),pop(),shift(),unshift(),sort(),reverse()数组的原型链缓存在vue中源代码,然后重写这些方法。当这些方法被触发时,会生成观察者数据,这意味着使用这些方法时不需要进行额外的操作。查看更新自动发生。推荐使用splice方法更好的自定义,因为splice可以在数组的任意位置进行删除/添加操作。vm.$set的实现原理是:如果目标是数组,直接使用数组的拼接方法触发相应的公式;对象,它会先判断属性是否存在,对象是否响应。最后,如果要对属性进行响应式处理,需要调用defineReactive方法进行响应式处理(defineReactive方法是Vue在初始化对象时,对对象属性使用Object.defineProperty调用的方法functionofdynamicaddinggetterandsetter)filter的作用,如何实现一个filter根据filter的名字,filter是用来过滤数据的,在Vue中使用filters来过滤数据。Filters不是数据会被修改,而是数据被过滤,改变用户看到的输出(computed属性和method方法都是用来修改数据处理数据格式的输出显示)。使用场景:当数据需要格式化时,比如需要处理时间、价格等数据格式的输出/显示。比如后端返回一个年月日的日期字符串,前端需要显示多少天前的数据格式。这时候可以使用过滤器来处理数据。过滤器是一个函数,它始终将表达式中的值作为函数的第一个参数。过滤器用在插值表达式{{}}和v-bind表达式中,然后放在运算符“|”之后表示。例如,显示金额时,将单位添加到商品价格中:

  • 商品价格:{{item.price|filterPrice}}
  • 过滤器:{filterPrice(价格){返回价格?('¥'+price):'--'}}Vue有哪些性能优化(1)在编码阶段将data中的数据最小化,data中的数据会添加getters和setters,相应的watcher会被收集。v-if和v-for必要时不能一起使用v-for在为每个元素绑定事件时使用事件代理。SPA页面使用keep-alive缓存组件。更多情况下,使用v-if代替v-showkey,保证只使用路由懒加载、异步组件防抖、节流Stream第三方模块按需导入长列表滚动到可视区域动态加载图片Lazy加载(二)SEO优化预渲染服务端渲染SSR(三)打包优化压缩代码TreeShaking/ScopeHoisting使用CDN加载第三方模块多线程打包happypacksplitChunks提取公共文件sourceMap优化(四)用户体验骨架screenPWA还可以使用缓存(客户端缓存,服务端缓存)优化,在服务端启用gzip压缩等。Vue封装的数组方法有哪些,如何实现页面更新在Vue中,Object.defineProperty用于拦截数据用于响应式处理,但是这种方法无法监听到数组内部的变化,数组长度的变化,数组变化拦截变化等等,所以这些操作需要被hack以便Vue可以监视更改。那么Vue是如何实现这些数组方法的实时更新的呢?下面是Vue中对这些方法的封装://缓存数组原型constarrayProto=Array.prototype;//implementarrayMethods.__proto__===Array.prototypeexportconstarrayMethods=Object.create(arrayProto);//需要展开的方法constmethodsToPatch=["push","pop","shift","unshift","splice","sort","reverse"];/***拦截变异方法并发出事件*/methodsToPatch.forEach(function(method){//缓存原始数组方法constoriginal=arrayProto[method];def(arrayMethods,method,functionmutator(...args){//执行并缓存原生数组函数constresult=original.apply(this,args);//响应式处理constob=this.__ob__;letinserted;switch(method){//push和unshift将被添加Index,所以需要手动观察器case"push":case"unshift":inserted=args;break;//对于拼接方法,如果传入第三个参数,也会添加一个索引,手动观察器也是必需的。案例“拼接”:插入=args.slice(2);休息;}//if(inserted)ob.observeArray(inserted);//获取插入的值并设置响应式监听器//通知更改ob.dep.notify();//通知依赖更新//返回原生数组方法returnresult的执行结果;});});简单来说,重写数组中的那些native方法,先获取数组的__ob__,也就是它的Observer对象,如果有新值,就调用observeArray继续观察新值的变化(也就是变化通过target__proto__==arrayMethods获取数组实例的类型),然后手动调用notify通知渲染观察者,执行更新。keep-alive使用场景及原理keep-alive是Vue内置的一个组件,可以实现组件缓存,在组件切换时不会卸载当前组件。两个常用的属性include/exclude允许有条件地缓存组件。activated/deactivated两个生命周期用于了解当前组件是否处于活动状态。keep-alive中也使用了LRU(leastrecentlyused)算法,选择最长时间没有被使用的组件进行淘汰。参考:前端vue面试题详解vue初始化页面闪烁问题在使用vue开发的时候,在vue初始化之前,由于div不在vue的控制之下,我们写的代码如果没有经过处理就容易出现花屏现象parsed,看到类似{{message}}的词,虽然这个时间一般都很短,但是让这个问题解决还是很有必要的。第一:在css中添加如下代码:[v-cloak]{display:none;}如果问题没有完全解决,添加style="display:none;":style="{display:'block'totherootelement}"简述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;i其实等同于:也用在自定义组件中:等价于:显然,custom-input与父组件的交互是这样的:父组件将searchText变量传递给custom-input组件,使用的prop命名为value;custom-input组件向父组件发送一个名为input的事件,父组件将接收到的值赋值给searchText;因此,自定义输入组件的实现应该类似于:Vue.component('custom-input',{props:['value'],template:``})Vue修饰符有哪些事件修饰符。stop阻止事件继续传播。prevent阻止标签的默认行为。capture采用事件捕获方式,即元素自身触发的事件先在这里处理,然后交给元素内部处理。self只有当event.target为当前元素本身时才会触发once事件时的处理函数,只会触发一次。被动告诉浏览器你不想阻止事件的默认行为。v-model修饰符。Lazy通过这个修饰符,转化为在change事件中重新同步。数字自动改变用户的输入值转换为数字类型.trim自动过滤user.enter.tab.delete(捕获“delete”和“backspace”键).esc.space.up.down.left.right系统修饰键输入的第一个和最后一个空格键盘事件的修饰符。ctrl.alt.shift.metaMousebuttonmodifier.left.right.middlev-for为什么要加key如果不使用key,Vue会使用一种最小化动态元素的方法,并尝试在适当的地方修改/重用相同类型的元素asmatchalgorithmkey是vnode在Vue中的唯一标识。通过这个key,我们的diff操作可以更准确、更快、更准确:因为有了key,就不是原地多路复用了。在同一个Node函数中a.key===b。在密钥比较中可以避免就地复用。所以它会更准确。更快:利用key的唯一性生成map对象获取对应节点,比遍历方式更快。v-show和v-if有什么区别?v-if是真正的条件渲染,因为它将确保条件块内的事件侦听器和子组件在切换期间被适当地销毁和重建;也很懒惰:如果在初始渲染时条件为假,什么也不做-条件块不会开始渲染,直到条件第一次变为真。v-show更简单-无论初始条件如何,元素始终呈现,并且根据CSS“显示”属性简单地切换。因此,v-if适用于运行时很少改变条件,不需要频繁切换条件的场景;v-show适用于需要非常频繁切换条件的场景。什么是插槽?效果如何?原理是什么?Slot,又称槽,是Vue的内容分发机制。组件内部的模板引擎使用slot元素作为承载和分发内容的出口。Slot槽是子组件的一个模板标签元素,是否显示以及如何显示这个标签元素由父组件决定。插槽分为三种类型:默认插槽、命名插槽和作用域插槽。Defaultslot:又称匿名检查,当slot没有指定name属性值时,默认显示一个slot,一个组件中只有一个anonymousslot。命名插槽:具有特定名称的插槽,即具有名称属性的插槽。一个组件中可以出现多个命名槽。scopeslot:defaultslot,namedslot的变种,可以是匿名slot也可以是namedslot,这个slot的区别在于子组件渲染scopeslot时,子组件内部的数据传递给父组件,父组件组件根据从子组件传递的数据决定如何渲染插槽。实现原理:子组件vm实例化时,获取父组件传入的slot标签内容,存放在vm.$slot中。默认插槽为vm.$slot.default,命名插槽为vm.$slot.xxx,xxx为插槽名称。组件在执行渲染函数时,遇到一个slot标签,将其替换为$slot中的内容。这时候,数据就可以传到槽中了。如果有数据,则该槽可以称为Scoped槽。