2025年前端Vue最常用的面试题总结(含详细代码解析)以下及答案_第1页
2025年前端Vue最常用的面试题总结(含详细代码解析)以下及答案_第2页
2025年前端Vue最常用的面试题总结(含详细代码解析)以下及答案_第3页
2025年前端Vue最常用的面试题总结(含详细代码解析)以下及答案_第4页
2025年前端Vue最常用的面试题总结(含详细代码解析)以下及答案_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2025年前端Vue最常用的面试题总结(含详细代码解析)以下及答案Vue响应式原理(Vue2与Vue3对比)Vue2通过`Object.defineProperty`对数据的`getter`和`setter`进行拦截,实现响应式。当访问数据时触发`getter`收集依赖(Watcher),修改数据时触发`setter`通知依赖更新。但该方案存在两个主要缺陷:无法检测对象新增/删除属性(需手动调用`Vue.set`/`Vue.delete`),无法监听数组长度变化或通过索引修改数组(需重写数组原型方法如`push`/`splice`)。示例代码(模拟Vue2响应式):```javascriptfunctiondefineReactive(obj,key,val){constdep=newDep();//依赖收集器Object.defineProperty(obj,key,{get(){if(Dep.target)dep.addSub(Dep.target);//收集当前活动的Watcherreturnval;},set(newVal){if(val===newVal)return;val=newVal;dep.notify();//通知所有Watcher更新}});}classDep{constructor(){this.subs=[];}addSub(sub){this.subs.push(sub);}notify(){this.subs.forEach(sub=>sub.update());}}Dep.target=null;//当前活动的Watcher```Vue3改用`Proxy`代理整个对象,能监听对象的所有操作(包括属性新增/删除、数组索引修改及长度变化),且无需重写数组方法。`Proxy`返回的是新对象,因此Vue3推荐使用`reactive`定义响应式对象,`ref`定义基本类型或对象的响应式(内部通过`reactive`包装成对象)。示例代码(模拟Vue3响应式):```javascriptfunctionreactive(target){returnnewProxy(target,{get(target,key,receiver){track(target,key);//收集依赖returnReflect.get(target,key,receiver);},set(target,key,value,receiver){constresult=Reflect.set(target,key,value,receiver);trigger(target,key);//触发更新returnresult;},deleteProperty(target,key){constresult=Reflect.deleteProperty(target,key);trigger(target,key);//删除属性时触发更新returnresult;}});}consttargetMap=newWeakMap();//存储目标对象的依赖functiontrack(target,key){if(!activeEffect)return;//无当前副作用则不收集letdepsMap=targetMap.get(target);if(!depsMap)targetMap.set(target,(depsMap=newMap()));letdep=depsMap.get(key);if(!dep)depsMap.set(key,(dep=newSet()));dep.add(activeEffect);//将副作用加入依赖集合}functiontrigger(target,key){constdepsMap=targetMap.get(target);if(!depsMap)return;constdep=depsMap.get(key);if(dep)dep.forEach(effect=>effect());//执行所有副作用}```组件通信的8种实现方式1.Props/$emit(父子通信):父组件通过`props`传递数据,子组件通过`$emit`触发自定义事件传递数据。父组件:```vue<template><Child:msg="parentMsg"@child-event="handleChildEvent"/></template><script>importChildfrom'./Child.vue';exportdefault{components:{Child},data(){return{parentMsg:'hello'};},methods:{handleChildEvent(val){console.log('子组件传递:',val);}}};</script>```子组件:```vue<template><button@click="sendToParent">传递</button></template><script>exportdefault{props:{msg:String},methods:{sendToParent(){this.$emit('child-event','world');}}};</script>```2.事件总线(EventBus)(任意组件通信):通过全局`Vue`实例或独立`EventEmitter`对象传递事件。Vue3中因`Vue`实例不再直接暴露,推荐使用`mitt`库替代。```javascript//初始化事件总线importmittfrom'mitt';constemitter=mitt();//组件A发送事件emitter.emit('user-login',{name:'张三'});//组件B监听事件emitter.on('user-login',(user)=>{console.log('登录用户:',user);});```3.Provide/Inject(跨层级通信):父组件通过`provide`提供数据,深层子组件通过`inject`注入。Vue3中支持响应式,需配合`reactive`或`ref`。父组件:```vue<scriptsetup>import{provide,ref}from'vue';constuserName=ref('张三');provide('user',userName);//提供响应式数据</script>```深层子组件:```vue<scriptsetup>import{inject}from'vue';constuser=inject('user');//直接获取响应式数据</script>```4.Vuex/Pinia(全局状态管理):Vue3推荐使用Pinia,API更简洁,支持组合式写法。Pinia示例:```javascript//stores/user.jsimport{defineStore}from'pinia';exportconstuseUserStore=defineStore('user',{state:()=>({name:'默认',age:18}),getters:{fullName:(state)=>`用户:${}`},actions:{updateName(newName){=newName;}}});//组件中使用import{useUserStore}from'./stores/user';constuserStore=useUserStore();console.log(userStore.fullName);//"用户:默认"userStore.updateName('李四');//触发状态更新```5.$parent/$children(直接访问父子实例):不推荐频繁使用,耦合性高,仅适用于简单场景。6.$attrs/$listeners(跨级传递属性/事件):`$attrs`包含未在子组件`props`中声明的父组件属性,`$listeners`包含父组件绑定的事件(Vue3中`$listeners`合并到`$attrs`)。子组件:```vue<template><GrandChildv-bind="$attrs"v-on="$attrs"/></template>```7.V-Model双向绑定:通过`modelValue`和`update:modelValue`实现,支持自定义修饰符。子组件:```vue<scriptsetup>import{defineProps,defineEmits}from'vue';constprops=defineProps({modelValue:String});constemit=defineEmits(['update:modelValue']);</script><template><input:value="modelValue"@input="emit('update:modelValue',$event.target.value)"/></template>```8.Ref/父组件获取子组件实例:父组件通过`ref`绑定子组件,直接调用子组件方法。父组件:```vue<template><Childref="childRef"/><button@click="callChildMethod">调用子组件方法</button></template><scriptsetup>import{ref}from'vue';importChildfrom'./Child.vue';constchildRef=ref(null);constcallChildMethod=()=>{childRef.value?.getChildData();//调用子组件方法};</script>```Vue3组合式API与选项式API的区别及适用场景选项式API(OptionsAPI)按功能类型(`data`/`methods`/`computed`)组织代码,适合小型项目或习惯传统类风格的开发者,但复杂组件中逻辑分散(如一个组件的多个`watch`和`methods`可能属于同一业务逻辑),导致维护困难。组合式API(CompositionAPI)通过`setup`函数或`<scriptsetup>`语法,按逻辑功能(如`useFetchData`/`useFormValidation`)组织代码,支持自定义`hook`复用逻辑,解决了选项式API的逻辑分散问题。适用于中大型项目,尤其是需要高度逻辑复用的场景。示例(组合式API实现表单校验):```javascript//hooks/useFormValidation.jsimport{ref,watch}from'vue';exportfunctionuseFormValidation(){constusername=ref('');consterror=ref('');watch(username,(newVal)=>{if(newVal.length<3)error.value='用户名至少3位';elseerror.value='';});return{username,error};}//组件中使用<scriptsetup>import{useFormValidation}from'./hooks/useFormValidation';const{username,error}=useFormValidation();</script>```虚拟DOM与Diff算法核心逻辑虚拟DOM(VirtualDOM)是真实DOM的JavaScript对象表示,通过`h()`函数(如`h('div',{class:'box'},'内容')`)提供。其核心优势是减少真实DOM操作次数:通过比较两次虚拟DOM的差异(Diff算法),仅更新变化的部分。Vue3的Diff算法优化了静态节点标记(`PatchFlag`),对动态内容进行精准比对。核心步骤:1.预处理:标记节点类型(文本、元素、组件等)和动态属性(如`class`/`style`)。2.层级比对:仅比较同一层级的节点(避免跨层级移动的复杂计算)。3.key的作用:通过唯一`key`标识节点,复用已存在的DOM元素。无`key`时,Vue按顺序比对,可能导致错误更新(如列表中间插入新元素时,后续节点全部重渲染)。示例(key的重要性):错误写法(无key):```vue<template><divv-for="iteminlist">{{item}}</div></template>```正确写法(有key):```vue<template><divv-for="iteminlist":key="item.id">{{}}</div></template>```VueRouter导航守卫与动态路由导航守卫用于控制路由的跳转流程,常见类型包括:-全局守卫:`router.beforeEach`(全局前置守卫)、`router.beforeResolve`(全局解析守卫)、`router.afterEach`(全局后置钩子)。-路由独享守卫:在路由配置中定义`beforeEnter`。-组件内守卫:`beforeRouteEnter`(进入前)、`beforeRouteUpdate`(更新前)、`beforeRouteLeave`(离开前)。动态路由通过`:参数名`定义,如`{path:'/user/:id',component:User}`,通过`$route.params.id`获取参数。示例(全局守卫实现权限控制):```javascriptrouter.beforeEach((to,from,next)=>{if(to.meta.requiresAuth&&!isLoggedIn()){next({path:'/login',query:{redirect:to.fullPath}});}else{next();}});```性能优化常见手段1.合理使用v-show与v-if:频繁切换用`v-show`(仅切换`display`),条件较少变化用`v-if`(卸载/重新渲染)。2.Computed缓存:依赖不变时直接返回缓存值,避免重复计算。3.列表渲染加key:通过唯一`key`标识节点,减少Diff时间。4.路由懒加载:使用`import()`语法动态加载组件,减小首包体积。```javascript{path:'/about',component:()=>import('./views/About.vue')}```5.组件懒加载:配合`Suspense`延迟加载非首屏组件。6.Keep-Alive缓存组件:缓存不常更新的组件,避免重复渲染。```vue<keep-alive><router-viewv-slot="{Component}"><component:is="Component"/></router-view></keep-alive>```7.减少响应式层级:避免深层嵌套对象(如`obj.a.b.c`),可通过`toRef`或`reactive`拆解。8.使用v-model修饰符:如`v-model.lazy`(输入框失去焦点时更新)、`v-model.number`(自动转换为数字)。Vue3新特性深度解析除响应式升级外,Vue3还引入以下关键特性:-Teleport:将组件渲染到DOM树的任意位置(如模态框脱离父容器限制)。```vue<teleportto="modal-container"><divclass="modal">内容</div></teleport>```-Suspense:配合异步组件,处理加载状态。```vue<templa

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论