欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

vue面试题

最编程 2024-02-22 12:29:59
...

1、$nextTick是什么$nextTick是在下次DOM更新循环结束之后执行延迟回调,可以保证回调函数一定实在DOM更新后执行的

2、Vue事件绑定原理原生事件绑定是通过addEventListener绑定给真实元素的,组件事件绑定是通过Vue自定义的$on实现的。如果要在组件上使用原生事件,需要加.native修饰符,这样就相当于在父组件中把子组件当做普通的HTML标签,然后加上原生事件。on、on、on、emit是基于发布订阅模式的,维护一个事件中心,on的时候将事件按名称存在事件中心里,称之为订阅者,然后emit将对应的事件进行发布,去执行事件中心里的对应的监听器。

3、Vue的路由hash模式和history模式的区别hash模式在浏览器中有个符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取而history是采用HTML5的新特性,底层使用pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更,history模:前端的URL必须和实际向后端发起请求的URL一致,后端如果缺少对/items/id的路由处理,将返回404错误。

4、Vue模板编译原理Vue的编译过程就是将template转化为render函数的过程,分为以下三步:第一步是将模板字符串转换成elementASTs(解析器)第二步是对AST进行静态节点标记,主要用来做虚拟DOM的渲染优化(优化器)第三步是使用elementASTs生成render函数代码字符串(代码生成器)

5、vue-loader是什么?使用它的用途有哪些vue-loader是解析.vue文件的一个加载器,跟template/js/style转换成js模块,使得.vue文件可以被浏览器解析计算属性和watch的区别computed计算属性,依赖其他的属性值,并且computed的属性值有缓存属性,当属性值变化的时候,下一次获取computed属性的时候才会重新计算computed的值。watch是一种观察的作用,用于监听某些数据的回调。每当所监听的数据发生变化时才能执行回调处理后续操作计算属性可以一对多,而watch是一对一

6、Vue的父子组件生命周期钩子函数执行顺序加载渲染过程父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount-

7、简述vue中diff算法原理diff算法是一种优化手段,将前后两个模块进行差异化对比,修补(更新)差异的过程叫做patch(打补丁),从以下几点来理解:

8、Vue声明周期Vue生命周期会经过八个阶段:beforeCreate(创建前)created(创建后)beforeMount(载入前)mounted(载入后)beforeUpdate(更新前)updated(更新后)beforeDestroy(销毁前)destroyed(销毁后)

9、vue如何兼容ie的问题vue本身不兼容IE10一下的,但是可以使用babel-polyfill插件改善兼容情况如何优化SPA应用的首屏加载速度慢的问题将公用的JS库通过script标签外部引入,减小app.bundel的大小,让浏览器并行下载资源文件,提高下载速度;在配置路由时,页面和组件使用懒加载的方式引入,进一步缩小app.bundel的体积,在调用某个组件时再加载对应的js文件;加一个首屏loading图,提升用户体验;使用预渲染插件prerender-spa-plugin生成对特定路由静态的html文件

10、v-for为什么需要绑定Key当Vue用v-for正在更新已渲染过的元素列表是,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue将不是移动DOM元素来匹配数据项的改变,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。为每项提供一个唯一key属性,在Vue的虚拟DOM算法里,在新旧nodes对比时辨识VNodes。如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素。

11、RouterLink在IE和Firefox中不起作用(路由不跳转)的问题方法一:只用a标签,不适用button标签方法二:使用button标签和Router.navigate方法

12、delete和Vue.delete删除数组的区别delete只是被删除的元素变成了empty/undefined其他的元素的索引还是不变。Vue.delete直接删除了数组改变了数组的长度。

13、nextTick使用场景和原理nextTick中的回调是在下次DOM更新循环结束之后执行的延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。主要思路就是采用微任务优先的方式调用异步方法去执行nextTick包装的方法。

14、Vuex页面刷新数据丢失怎么解决?需要做vuex数据持久化,一般使用本地储存的方案来保存数据,可以自己设计存储方案,也可以使用第三方插件。推荐使用vuex-persist(脯肉赛斯特)插件,它是为Vuex持久化储存而生的一个插件。不需要你手动存取storage,而是直接将状态保存至cookie或者localStorage中。或使用pinia解决

15、v-model原理v-model只是语法糖而已。v-model在内部为不同的输入元素使用不同的property并抛出不同的事件。text和textarea元素使用valueproperty和input事件;checkbox和radio使用checkedproperty和change事件;select字段将value作为prop并将change作为事件。注意:对于需要使用输入法的语言,你会发现v-model不会在输入法组合文字过程中得到更新。在普通元素上:inputv-model=‘sth’inputv-bind:value=‘sth’v-on:input=‘sth=$event.target.value’

16、单页面应用和多页面应用区别及优缺点单页面应用就是指只有一个主页面的应用,浏览器一开始要加载所有必须的html,js,css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。多页面是指一个应用中有多个页面,页面跳转时是整页刷新.单页面的优点是用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小;前后端分离;页面效果会比较炫酷(比如切换页面内容时的专场动画)。单页面缺点是不利于seo;导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理);初次加载时耗时多;页面复杂度提高很多

17、为什么vue中data必须是一个函数对象为引用类型,当重用组件时,由于数据对象都指向同一个data对象,当在一个组件中修改data时,其他重用的组件中的data会同时被修改;而使用返回对象的函数,由于每次返回的都是一个新对象(Object的实例),引用地址不同,则不会出现这个问题

18、生命周期钩子是如何实现的Vue的生命周期钩子核心实现是利用发布订阅模式先把用户传入的生命周期钩子订阅好(内部采用数组的方法存储)然后在创建组件实例的过程中会一次执行对应的钩子方法(发布)

19、Vue修饰符有哪些?事件修饰符.stop阻止事件继续传播.prevent阻止标签默认行为.capture使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理.self只当在event.target是当前元素自身时触发处理函数.once事件只会触发一次.passive告诉浏览器你不想阻止事件的默认行为v-model的修饰符.lazy通过这个修饰符,转变为在change事件再同步.number自动将用户输入值转化为数值类型.trim自动过滤用户输入的收尾空格键盘事件修饰符.enter.tab.delete(捕获“删除”和“退格”键).esc.space.up.down.left.right系统修饰符.ctrl.alt.shift.meta鼠标按钮修饰符.left.right.middle

20、scoped的原理是什么添加scoped属性的组件,会给HTML的DOM节点加一个不重复属性标志唯一性,实现类似于“作用域”的作用,不影响全局,这样添加的样式就是给这个唯一标示添加,达到样式隔离的效果

21、写过自定义指令吗?原理是什么?指令本质上是装饰器,是vue对HTML元素的扩展,给HTML元素添加自定义功能。vue编译DOM时,会找到指令对象,执行指令的相关方法。自定义指令有五个生命周期(也叫钩子函数),分别是bind、inserted、update、componentUpdated、unbindbind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted:被绑定元素插入父节点时调用。update:被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较前后的绑定值。componentUpdated:被绑定元素所在模板完成一次更新周期时调用。unbind:只调用一次,指令与元素解绑时调用。原理:在生成ast语法树时,遇到指令会给当前元素添加directives属性通过genDirectives生成指令代码在patch前将指令的钩子提取到cbs中,在patch过程中调用对应的钩子。当执行指令对应钩子函数时,调用对应指令定义方法。

22、Vue的v-show和v-if区别v-if直接影响组件是否被渲染v-show是决定元素display的值是不是none当需要在显示与隐藏之间进行频繁的切换操作时,就使用v-show。当只有一次切换时,我们就使用v-if。

23、Vue.set方法原理了解Vue响应式原理的同学都知道在两种情况下修改Vue是不会触发视图更新的。在实例创建之后添加新的属性到实例上(给响应式对象新增属性)直接更改数组下标来修改数组的值。Vue.set或者说是$set原理如下因为响应式数据我们给对象和数组本身新增了ob属性,代表的是Observer实例。当给对象新增不存在的属性,首先会把新的属性进行响应式跟踪然后会触发对象ob的dep收集到的watcher去更新,当修改数组索引时我们调用数组本身的splice方法去更新数组。

24、v-for与v-if的优先级v-for比v-if优先,如果每一次都需要遍历整个数组,将会影响速度

25、Vue.extend作用和原理官方解释:Vue.extend使用基础Vue构造器,创建一个“子类”。参数是一个包含组件选项的对象。其实就是一个子类构造器,是Vue组件的核心api。实现思路就是使用原型继承的方法返回了vue的子类,并且利用mergeOptions把传入组件的options就和父类的options进行了合并。

26、Vue.mixin的使用场景和原理在日常开发中,我们经常会遇到在不同组件中经常用到一些相同或者相似的代码,这些代码的功能相对独立,可以通过vue的mixin功能抽离公共的业务逻辑,原理类似“对象的继承”,当组件初始化时会调用mergeOptions方法进行合并,采用策略模式针对不同的属性进行合并。当组件和混入对象含有相同名选项时,这些选项将以恰当的方式进行“合并”。

27、vue中的ref是什么ref被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的$refs对象上。如果在普通的DOM元素上使用,引用指向的就是DOM元素;如果用在子组件上,引用就指向组件实例

28、Vue改变数组有时候无法触发视图更新是什么原因Vue是通过Object.defineProperty()来实现双向数据绑定的。把一个普通JavaScript对象传给Vue实例的data选项,Vue将遍历此对象所有的属性,并使用Object.defineProperty把这些属性全部转为getter/setter,当使用push(),pop(),shift(),unshift(),splice(),sort(),reverse()等数组原生方法操作数据的手可以引发页面更新,但是如果直接通过索引更改数组内容就会有问题,这个时候可以通过Vue.set解决

29、能说下vue-router中常用的路由模式和实现原理吗?hash模式location.has的值实际就是URL中#后面的东西。它的特点在于:hash虽然出现URL中,但不会被包含在HTTP请求中,对后端完全没有影响,因此改变hash不会重新加载页面。可以为hash的改变添加监听事件window.addEventListener(“hashchange”,funcRef,false)每一次改变hash(window.location.hash),都会在浏览器的访问历史中增加一个记录,利用hash的以上特点,就可以实现前端路由“更新视图但不重新请求页面”的功能了特点:兼容性好但是不美观history模式利用HTML5HistoryInterface中新增的pushState()和replaceState()方法。这两个方法应用于浏览器的历史记录站,在当前已有的back、forward、go的基础上,他们提供了对历史记录进行修改的功能。这两个方法有个共同点:当调用他们修改浏览器历史记录栈后,虽然当前URL改变了,但浏览器不会刷新页面,这就为单页面应用前端路由“更新视图但不重新请求页面”提供了基础特点:虽然美观,但是刷新会出现404需要后端进行配置。

30、vuex的store是什么vuex就是一个仓库,仓库里放了很多对象。其中state就是数据源存放地,对应于一般vue对象里面的datastate里面存放的数据是响应式的,vue组件从store读取数据,若是store中的数据发生改变,依赖这相数据的组件也会发生更新它通过mapState把全局的state和getters映射到当前组件的computed计算属性

31、Vue0编译做了哪些优化?a.生成BlocktreeVue.jsx的数据更新并触发重新渲染的粒度是组件级的,单个组件内部需要遍历该组件的整个vnode树。在0里,渲染效率的快慢与组件大小成正相关:组件越大,渲染效率越慢。并且,对于一些静态节点,又无数据更新,这些遍历都是性能浪费。Vue.js0做到了通过编译阶段对静态模板的分析,编译生成了Blocktree。Blocktree是一个将模版基于动态节点指令切割的嵌套区块,每个区块内部的节点结构是固定的,每个区块只需要追踪自身包含的动态节点。所以,在0里,渲染效率不再与模板大小成正相关,而是与模板中动态节点的数量成正相关b.slot编译优化Vue.jsx中,如果有一个组件传入了slot,那么每次父组件更新的时候,会强制使子组件update,造成性能的浪费。Vue.js0优化了slot的生成,使得非动态slot中属性的更新只会触发子组件的更新。动态slot指的是在slot上面使用v-if,v-for,动态slot名字等会导致slot产生运行时动态变化但是又无法被子组件track的操作。c.diff算法优化

32、v-on常用修饰符.stop阻止事件向上冒泡。.prevent阻止当前事件的默认行为.self事件绑定的元素本身触发时才触发回调.once绑定的事件只会被触发一次

33、vue中使用了哪些设计模式?工厂模式-传入参数即可创建实例虚拟DOM根据参数的不同返回基础标签的Vnode和组件Vnode。单例模式-整个程序有且仅有一个实例vuex和vue-router的插件注册方法install判断如果系统存在实例就直接返回掉。发布-订阅模式。(vue事件机制)观察者模式。(响应式数据原理)装饰器模式(@装饰器的用法)策略模式,策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现方案-比如选项的合并策略。

34、Vue0新特性——CompositionAPI与React.js中Hooks的异同点a.React.js中的Hooks基本使用ReactHooks允许你"勾入"诸如组件状态和副作用处理等React功能中。Hooks只能用在函数组件中,并允许我们在不需要创建类的情况下将状态、副作用处理和更多东西带入组件中。React核心团队奉上的采纳策略是不反对类组件,所以你可以升级React版本、在新组件中开始尝试Hooks,并保持既有组件不做任何更改。useState和useEffect是ReactHooks中的一些例子,使得函数组件中也能增加状态和运行副作用。我们也可以自定义一个Hooks,它打开了代码复用性和扩展性的新大门。b.VueCompositionAPI基本使用VueCompositionAPI围绕一个新的组件选项setup而创建。setup()为Vue组件提供了状态、计算值、watcher和生命周期钩子。并没有让原来的API(Options-basedAPI)消失。允许开发者结合使用新旧两种API(向下兼容)。c.原理Reacthook底层是基于链表实现,调用的条件是每次组件被render的时候都会顺序执行所有的hooks。Vuehook只会被注册调用一次,Vue能避开这些麻烦的问题,原因在于它对数据的响应是基于proxy的,对数据直接代理观察。(这种场景下,只要任何一个更改data的地方,相关的function或者template都会被重新计算,因此避开了React可能遇到的性能上的问题)。React中,数据更改的时候,会导致重新render,重新render又会重新把hooks重新注册一次,所以React复杂程度会高一些。

35、prop是什么prop是共给父组件给子组件传值得一个重要属性,需要在子组件内规划好该组件需要得props以及每个prop数据格式默认值等等vue组件通信父传递子:父:自定义属性名+数据(要传递)=>:value=“数据”子:props["父组件上的自定义属性名“]=>进行数据接收)子传递父:在父组件中注册子组件并在子组件标签上绑定自定义事件的监听。子:this.$emit(‘自定义事件名称’,数据)子组件标签上绑定@自定义事件名称=‘回调函数’父:methods:{自定义事件(){//逻辑处理}}兄弟组件:通过*通信letbus=newVue()vuex可以满足任何场景通信需求

36、query传参和params传参有什么区别params传参可以提前在路由离定义好成为路由的一部分而query不需要params传参或存在参数刷新丢失的情况而query不会

37、vue-router有几种导航钩子全局导航钩子组件内的钩子单独路由独享组件

38、keep-alive使用场景和原理keep-alive是Vue内置的一个组件,可以实现组件缓存,当组件切换时不会对当前组件进行卸载。常用的两个属性include/exclude,允许组件有条件的进行缓存。两个生命周期activated/deactivated,用来得知当前组件是否处理活跃状态。keep-alive运用了LRU算法,选择最近最久未使用的组件予以淘汰。

39、vue-router路由钩子函数是什么?执行顺序是什么?路由钩子的执行流程,钩子函数种类有:全局守卫、路由守卫、组件守卫。完整的导航解析流程:导航被触发。在失活的组件里调用beforeRouterLeave守卫。调用全局的beforeEach守卫。在重用的组件调用beforeRouterUpdate守卫(2+)。在路由配置里面beforeEnter。解析异步路由组件。在被激活的组件里调用beforeRouterEnter。调用全局的beforeResolve守卫(5+)。导航被确认。调用全局的afterEach钩子。触发DOM更新。调用beforeRouterEnter守卫中传给next的回调函数,创建好的组件实例会作为回调函数的参数传入。

40、为什么虚拟dom会提高性能?虚拟dom相当于在js和真实dom中间加了一个缓存,利用domdiff算法避免了没有必要的dom操作,从而提高性能。具体实现步骤如下:用JavaScript对象结构表示DOM树的结构;然后用这个树构建一个真正的DOM树,插到文档当中;当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异;把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了。

41、文件夹assets和static的区别assets和static两个都是存放静态资源文件,但是assets中存放的静态资源文件在项目打包时会进行编译,而static不会

42、$route和$router的区别$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。$router是’路由实例’对象包括了路由的跳转方法,钩子函数等

43、Vue中双向数据绑定是如何实现的vue双向数据绑定是通过数据劫持结合发布订阅模式的方式来实现的,也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;vue双向数据绑定,其核心是Object.defineProperty()方法

44、你都做过哪些Vue的性能优化?这里只列举针对Vue的性能优化,整个项目的性能优化是一个大工程。对象层级不要过深,否则性能就会差。不需要响应式的数据不要放在data中v-if和v-show区分使用场景computed和watch区分场景使用v-for遍历必须加key,key最好是id值,且避免同时使用v-if大数据列表和表格性能优化-虚拟列表/虚拟表格防止内部泄露,组件销毁后把全局变量和时间销毁图片懒加载路由懒加载异步路由第三方插件的按需加载适当采用keep-alive缓存组件防抖、节流的运用服务端渲染SSRor预渲染

45、Vue0里为什么要用ProxyAPI替代definePropertyAPI?响应式优化。a.definePropertyAPI的局限性最大原因是它只能针对单例属性做监听。Vuex中的响应式实现正是基于defineProperty中的descriptor,对data中的属性做了遍历+递归,为每个属性设置了getter、setter。这也就是为什么Vue只能对data中预定义过的属性做出响应的原因,在Vue中使用下标的方式直接修改属性的值或者添加一个预先不存在的对象属性是无法做到setter监听的,这是defineProperty的局限性。b.ProxyAPI的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作,这就完全可以代理所有属性,将会带来很大的性能提升和更优的代码。Proxy可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。c.响应式是惰性的在Vue.jsx中,对于一个深层属性嵌套的对象,要劫持它内部深层次的变化,就需要递归遍历这个对象,执行Object.defineProperty把每一层对象数据都变成响应式的,这无疑会有很大的性能消耗。在Vue.js0中,使用ProxyAPI并不能监听到对象内部深层次的属性变化,因此它的处理方式是在getter中去递归响应式,这样的好处是真正访问到的内部属性才会变成响应式,简单的可以说是按需实现响应式,减少性能消耗。

46、Vue0是如何变得更快的?a.diff方法优化Vuex中的虚拟dom是进行全量的对比。Vue0中新增了静态标记(PatchFlag):在与上次虚拟结点进行对比的时候,值对比带有patchflag的节点,并且可以通过flag的信息得知当前节点要对比的具体内容化。b.hoistStatic静态提升Vuex:无论元素是否参与更新,每次都会重新创建。Vue对不参与更新的元素,只会被创建一次,之后会在每次渲染时候被不停的复用。c.cacheHandlers事件侦听器缓存默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化但是因为是同一个函数,所以没有追踪变化,直接缓存起来复用即可。

47、如何让CSS只在当前组件中起作用将当前组件的

48、vuex是什么?有哪几种属性Vuex是一个专为Vue.js应用程序开发的状态管理模式。它有5种属性,分别是state、getter、mutation、action、module

49、vue路由传参数有几种方式使用query方法传入的参数使用this. r o u t e . q u e r y 接受 使用 p a r a m s 方式传入的参数使用 t h i s . route.query接受使用params方式传入的参数使用this. route.query接受使用params方式传入的参数使用this.route.params接受

50、Vuex为什么要分模块并且加命名空间?模块:由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能会变得相当臃肿。为了解决以上问题,Vuex允许我们将store分割成模块(module)。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块。命名空间:默认情况下,模块内部的action、mutation、getter是注册在全局命名空间的—这样使得多个模块能够对同一mutation或action做出响应。如果希望你的模块具有更高的封装度和复用性,你可以通过添加namespaced:true的方式使其成为带命名的模块。当模块被注册后,他所有getter、action、及mutation都会自动根据模块注册的路径调整命名。使用过VueSSR吗?说说SSRSSR也就是服务端渲染,也就是将Vue在客户端把标签渲染成HTML的工作放在服务端完成,然后再把html直接返回给客户端。优点:SSR有着更好的SEO、并且首屏加载速度更快。缺点:开发条件会受限制,服务器端渲染只支持beforeCreate和created两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于Node.js的运行环境。服务器会有更大的负载需求。

51、vue获取数据在哪个周期函数在created/beforeMount/mounted中都可以如果不需要等待页面渲染完毕最好就在created里请求

52、vuex的mutation有什么使用技巧mutation里不能进行异步操作,mutation提交的是对store数据的更改,一般调用mutation的都是action,action类似于muation,不同在于:action提交的是mutation,而不是直接变更store状态,action可以包含任意异步操作

53、keep-alive的作用是什么包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染,实现缓存组件