VUE八股文
问:你认为Vue的核心是什么?
1.组件化:Vue会将重复的vue组件进行抽取,我们可以通过暴露并导入的方式来使用我们编写好的组件,提高了代码的复用性并减少代码之间的耦合度。
2.响应式编程:Vue的设定就是不建议开发者使用DOM直接进行数据操作,当我们修改Vue中的数据的时候页面中的数据也会进行修改,视图会随着数据的改变而进行视图的更新。
3.虚拟DOM:Vue会去维护一个真实DOM的副本也就是一个虚拟的DOM,只有在真正需要的时候才会将变化更新到真正的DOM上。
问:你刚刚说到了组件化,能具体一些吗?
一个.vue文件就可以将其看作一个组件,在该文件中我们可以编写 html, js,css。
优点:
- 好维护:因为组件都是统一调用的,在修改时也只需要在组件中修改即可,减少了代码的耦合度。
- 好调试:在调试整体界面时,如果不需要某个组件的话,删除导入操作即可。
问:有了解过MVVM模式吗?
在MVVM中,主要就是三个部分,Model,ViewModel,View。
1.Model:数据层,主要就是负责数据的存储和处理操作,就比如在Vue中data中的数据,向后端发送请求获取的数据操作。
2.View:视图层,主要就是通过传来的数据渲染到视图界面上。
3.ViewModel:视图模型层,也就是Model和View交互的中间商,VM会从Model中获取对应的数据传给View层,并且呢,VM也会收集View层传来的用户输入并传给Model,实现双向绑定。
MVVM模式有什么优点呢?
在View和Model的中间加一层,那无非呢就是为了解耦合,将业务逻辑和用户界面的渲染分离开来。也是因为二者的分离,在后续维护的时候,只需要针对其中一个部分修改即可。
问:在Vue中data为什么使用函数形式而非对象形式呢?
在Vue中我们通常会定义组件,并且呢,组件会被多次使用,使用函数的话,就可以保证每一个组件中的数据域独立私有的,如果使用对象的话每一个组件使用的data都是该对象的引用,数据并非私有(函数有独立的作用域)
问:v-if和v-show有什么区别?
1.在创建和销毁方面,v-if会在会根据属性值的改变而进行创建或销毁,而v-show只会在加载视图的时候进行创建,在数据值变成false的时候并不会做销毁而是将css的display设置为false。
2.在初始化方面:v-if是惰性加载的,当刚开始属性值为false的时候是不会进行创建的,而v-show在初始化的时候就会进行创建。
3.当业务上为频繁切换的时候,比较适合使用v-show,减少创建及销毁的性能开销。
反之使用v-if,因为其为惰性可以保证在初始化的时候减少不必要的创建的性能开销。
问:使用v-for的时候为什么要加key呢?
1.保证数据渲染的性能,当我们设置了key的唯一标识的时候,集合数据发生修改的时候,vue会尽可能的使用原来的组件进行更新(而不是直接销毁组件),通过key来锁定对应的节点。
2.保证数据不丢失,在组件中我们通常会使用输入框等输入组件,为了保证数据在页面的正常展示,我们需要使用key定位。
3.添加key可以为虚拟dom节点添加标识,在diff算法中使用key来对定位真实dom节点,做移动,新增和删除的操作。当两个key相同的节点此时就会复用节点。(要保证key的唯一性)
问:computed和watch的区别是什么呢?
1.computed支持缓存,而watch不支持。
2.computed只有在依赖的数据发生改变时才会运行,而watch则会在监听的数据发生改变时执行。
3.watch支持执行异步,而computed不支持。
4.computed需要修改数据的时候需要使用set和get函数,而 watch则可以直接修改。
5.watch支持深度监听,当监听的是对象的时候,对象中的属性发生修改了也会执行watch中的方法。
问:有了解过虚拟dom吗?
1.虚拟dom节点我们可以了解成真实dom的副本,通过多数的dom节点过程dom树,该dom树中包含了真实dom的属性等数据。
2.当数据发生改变的时候,vue会生成新的虚拟dom树并和旧的虚拟dom进行比较,采用diff算法来实现的,比较到两个虚拟dom的不同位置,最终将这个不同的数据更新到真实的dom中,减少了不必要的真实dom操作。
问:说到虚拟dom,你有了解过diff算法吗?
1.同级比较:虚拟dom在做比较的时候,只会在同层进行比较而不是跨层比较,此时的时间复杂度就会由n^3优化成n。(同层比较 属性和子节点)
2.设置唯一key:虚拟dom中的每一个节点都会设置key,通过key来定位真实的节点并进行移动,新增,删除操作。减少真实dom的更新操作。(在两个节点的)
问:有了解过vue的生命周期吗?(vue有几个什么钩子函数)
1.beforeCreate:在实例被初始化之之后,并设置数据和事件的监听配置之前调用。
2.created:实例创建完成的时候调用,此时可以获取数据,但是dom还没有被渲染出来。
3.beforeMount:在实例被挂载之前被调用,dom还没有被渲染出来,和created的用法差不多。
4.Mounted:在实例挂载完成之后被调用,此时dom已经被渲染出来了。
5.beforeUpdate:在dom数据被修改之前调用,此时我们还可以获取到修改前的dom数据。
6.Updated:在dom数据更新完成后调用,该过程中使用到diff算法。
7.beforeDestory:在实例被销毁之前调用,此时我们还是可以获取到数据。
8.Destoryed:在实例被销毁后调用。
问:说到钩子函数,你平时有用到吗?
1.使用beforeCreate和created钩子函数做加载圈,在beforeCreate做loading的渲染,在created中调用请求获取数据并结束loading效果。
2.使用mounted在初始化时调用某个函数,完成数据初始化的操作。
问:如果现在有子父组件,那么它们钩子函数的执行顺序是怎么样的呢?
1.在加载渲染的时候:父亲的beforeCreate -> 父亲的created ->父亲beforeMount -> 孩子的beforeCreate -> 孩子的created -> 孩子的beforeMount ->孩子的mounted -> 父亲的mounted。
2.在数据修改的时候:父亲的beforeUpdate -> 孩子的 beforeUpdate ->孩子的updated ->父亲的updated。
3.在数据销毁的时候:父亲的beforeDestory -> 孩子的beforeDestory ->孩子的Destoryed -> 父亲的Destoryed。
问:组件之间的通信有那些呢?
1.使用props实现父传子,$emit实现子传父。(在父组件中编写回调函数并监听对应的事件,在子组件中触发对应的事件)
2.使用Event Bus事件总线来实现任意组件之间的通信。传递数据的组件使用$emit,接收数据的组件使用$on。
3.使用provide和inject来实现爷孙组件之间的通信,在爷组件中编写provide函数,在孙组件中inject对应的provide函数。(inject['自定义函数名'])
4.使用$childen来实现孩子组件获取父组件中的信息,使用$parent来实现父组件获取子组件中的信息。
5.使用vueX来实现任意组件之间的通信,使用pinia也是一样的效果,设置数据仓库store。
6.使用$ref,使用$ref.child就可以让父组件获取子组件的信息。
问:有了解过$nextTick吗?
它是dom更新的优化策略,在循环更新结束后以及在数据更新结束后会立刻调用$nextTick方法。
举个例子:我们对每隔数据做循环更新,vue会异步的开启一个更新队列,将每次关系的结果存储到队列中,在循环结束就会调用$nextTick方法,处理更新队列中的数据,此时视图只更新一次,而没有$nextTick的话呢,数据的每一次循环修改就会导致一次试图的更新。
问:你有了解过keep-alive吗?
重要的作用就是将被keep-alive的组件进行缓存,防止组件重新渲染(保留数据),特别适用在频繁切换状态的场景。
其有对应两个钩子函数,actived当组件被激活时被调用,deactived当被组件被缓存时被调用。
问:你有了解过插槽吗?
我目前使用的比较多的插槽就是匿名插槽,具名插槽,作用域插槽。
1.匿名插槽:就在子组件中预留一个插槽位置,父组件传递template。
2.具名插槽:就在在子组件中定义有多个插槽,在父组件中我们会为template设置对应的id。
3.作用域插槽:可以让父组件获取子组件中的数据,我们在子组件中设置v-bind,在父组件中设置#进行接收子组件中对应的数据。
问:v-model的数据双向绑定的原理是什么?
v-model本质就是个语法糖,它是由v-bind和v-on构成的,首先会让输入框通过v-bind绑定对应的数据,在使用v-on绑定input事件,当数据发生改变时,就会将输入框中的数据赋值到绑定的数据上。
问:Vue2和Vue3的响应式有什么区别呢?
Vue2采用object.defaineproperty来实现响应式的,object.defaineproperty可以检测到对象属性的查询和修改,但是检测不到对象属性的新增和删除。
Vue3采用proxy实现的,它解决了object.defaimeproperty的短板。
问:路由中的传参和获取参数的方法有哪些?
传参的话,主要就是两种分别是:query和params。
- param主要就是通过:id的形式来实现传参的,有点类似restful风格。
- query主要就是通过路径拼接来实现传参的,就是 ?后跟参数。
获取参数的话就是通过:
- this.$route.params.xxx来获取参数。
- this.$route.query.xxx来获取参数。
问:VueX有了解过吗?
作用:用来集中管理组件状态的。
属性:
state属性:初始的数据。
getter属性:基于state操作后的数据。
mutations:更新数据。
action:执行mutions中的函数,做异步操作。