# 2023秋招面试—Vue篇
# 1.Vue的基本原理
Vue通过重写data的getter和setter方法,让数据在被渲染时,把所有用到该数据的订阅者,存放到订阅者列表中去;
当数据被修改时,Notify方法通知所有订阅者Watcher,来达到重新渲染的目的。
举个简单的栗子🌰:
《西游记》中的妖怪(Watcher)时刻惦记(订阅)着唐僧(Data),想吃唐僧肉,孙悟空(Component)在听到(get搜集依赖)唐僧被抓的消息后,做出反应(set触发依赖),准备救出师傅。于是来到了妖怪(Watcher)的老巢,跟它大战几个回合后,成功救出唐僧(Data),达到重新踏上(渲染)西天取经(Vittual DOM Tree)的目的!
# 2.Object.defendeProperty()来进行数据劫持有什么缺点?
Vue2中通过下标的方式修改或新增数组属性,Object.defineProperty()检测不到数据的变化,在对属性监听时,如果嵌套对象,需要深层监听,照成性能的浪费;
Vue3通过使用Proxy监听整个对象,Proxy最大的好处是可以监听到任何方式数据的变化,当也存在兼容性问题,因为它是ES6的语法。
# 3.MVVM、MVC、MVP的区别
MVVM(Model、View、ViewModel):Model与ViewModell通过双向数据绑定, 当Model中的值发生改变的时候,就会触发更新View,View中用户操作改变的数据也会与Model同步。
MVC(Model、View、Controller):比较传统的开发模式,Model层发生变化的时候会通知有关的View层更新页面,Controller中的事件触发后,通过调用Model进行修改,从而更新View页面。
MVP(Model、View、Presenter):通过Presenter层来对View层和Model层进行解耦,View层的接口暴露给Presenter,在Presenter中,将Model和View的变化绑定在一起,已实现Model和View的同步更新。
# 4.computed 和 watch 、methods 的区别
两个互补的属性,
computed : computed 的值会默认走缓存路径,但是不支持异步,有异步操作时,无法监听到变化;
watch: 不支持缓存,支持异步监听,当数据变化时,会立马触发相应的操作,监听的两个参数newValue、oldValue。
methods: 只要把方法用到模板上,每一次变化就会重新渲染视图,性能开销大。
# 5.v-if 和 v-for 的区别
操作手段:v-if动态添加或删除DOM元素;v-show则是通过设置DOM元素的display属性控制显示或隐藏。
编译条件:v-if是惰性的,如果初始条件为假,那么则什么都不做;v-show无论首次条件是否为真,都会被编译,保留DOM元素。
编译阶段:v-if切换有一个局部编译/卸载的过程,切换过程中会销毁或重新内部的事件监听和子程序;v-show只是简单的切换样式。
性能消耗:v-if切换性能消耗大; v-show初始化渲染消耗大。
# 6.v-model是如何实现的?
v-model本质上是父子组件通信的语法糖,这个语法糖是固定的,也就是说属性必须是value,方法名必须是input,动态的绑定到表单元素value属性上,然后监听input事件。
# 7.v-if 和 v-for 为什么不能一起用?
这个问题官方文档已经做了解释,v-for的优先级比v-if高,如果一起使用,每次遍历都会判断一下true还是false,这样就照成了资源的浪费。
# 8.Vue性能优化有哪些?
编译阶段:①尽量减少data中的数据,data中的数据会增加getter和setter,也会搜集对于的Watcher;
②使用异步组件、JS代码注意防抖和节流,图片使用懒加载等;
③第三方模块按需导入,key保持唯一,SPA页面采用keep-alive缓存组件。
打包优化:①抽离公共文件,压缩代码,使用CDN引入第三方模块
用户体验:①骨架屏,服务端开启gzip压缩等。
# 9.对SPA单页面理解,有什么优缺点?
SPA(single-page applications):单页面应用程序,在初始化加载页面时,SPA不会对因为用户的操作而重新加载或跳转。
优点:用户体验好,对服务器压力小,早期公司官网就是使用的这种方式。
缺点:初次加载耗时,前进后退路由管理比较麻烦。
# 10.简单说下Vue生命周期
Vue生命周期分为
初始化阶段 beforeCreate、created
挂载阶段:beforeMonnt、monted
更新阶段:beforeUpdate、updated
销毁阶段:beforeDestroy、destroyed(Vue3中修改为beforeUnmont、Unmonted)
跟踪组件:renderTracked
触达重新渲染:renderTiggered
# 11.组件通信的方式有哪些?
①父子组件通信:父组件通过props向子组件传递数据;子组件通过$emit和父组件通信。
②兄弟组件通信:本质上创建一个空的Vue实例来做消息传递对象,通信组件引入该实例,通过这个实例监听和触发事件,从而实现消息的传递。
③任意组件通信:使用eventBus,创建一个事件中心,相当于中转站,用它来传递和触发事件。这个时候可以使用vuex,vuex的思想就是将一些公共的数据抽离出来,将它作为一个全局的变量来管理,让后其他组件可对这个公共数据进行读写操作。
# 12.Vuex的原理
使用场景:在复杂组件之家传递数据,相当于存储共享变量的概念。
实现了一个单项数据流,在全局下拥有一个存储共享变量的容器,
当Vue 组件触发某些事件或动作(Actions)时,Actions 将这些动作携带的数据(commit)提交到Mutations中,
Mutatians就去改变 State中的数据,
State 中的数据改变后,最后重新渲染到Vue组件上;
# 13.路由的hsah 和 history 的区别?
hsah 模式:不包含在http请求内,用来指导浏览器动作,修改hash不会重新加载页面;
history 模式: 使用传统的路由分发模式,history API分两大类,修改历史状态和切换历史状态;
修改历史状态,可使用pushState()、replaceState() 两个方法来修改浏览器历史记录栈;
切换历史状态,可使用 forward()、back()、 go()三个方法分别控制前进、后退、跳转操作。
# 14.Vuex 中Active 和Mutation 的区别?
Mutation 是同步的,Active则是异步,不能直接修改 State,必须经过Mutation
# 15.Vue 3 有哪些更新?
首先是 Composition API ,强调的是逻辑组合,将Vue底层多个响应式API 组合成 setup() 的形式;
一个组件支持多个根元素 fargment ;
Teleport,
Suspense,
尺寸上利用了 tree-shaking,打包时会去除不用的功能;
# 16.Diff 算法了解吗?
Diff是发生在两个虚拟Dom上的,①首先通过key值找到不需要移动的相同节点;②判断该节点的子节点,如果新的Chilren 没有子节点,而旧的有,则删除旧子节点;③相反,如果新的Chilren 有子节点,旧的没有,则给旧的添加新节点,然后继续递归子节点;
# 17.data 为什么是一个函数,而不是一个对象?
在Vue官网风格指南中有提到,如果data是一个对象的话,那么当前组件的数据就会被其他不相干组件所共享,这样就不方便管理独立的组件;
# 18.Vue 和 React 有什么异同?
相同点:
①都提倡组件化开发的思想,将多个应用才分成明确的模块,提高复用性;
②都有props 的概念,允许组件之间传递参数;
③都使用了虚拟dom来提高重绘性能;
不同点:
①模块编写方面,Vue提倡写近似于HTML的模板,只是多了一些属性;而React 提倡Jsx的写法;
②虚拟dom方面处理方面,Vue在组件层面使用了 Watcher, 组件内部 Vdom 做diff算法;React 则是类似于 CPU调度的逻辑,将Vdom 这棵树微观上变成了链表,利用浏览器空闲时间做 Diff算法;
# 19.$nextTick() 原理?
本质上是对Event Loop 的应用,利用Promise, setTimeout 等原生方法实现Vue 内部的异步回调;
# 20.Vuex 和 Redux 的区别
Vuex 借鉴了Redux的原理,将Store作为全局的数据中心,进行模块管理,并改进了Redux的Action和Reducer函数,以mutations变化函数取代Reducer,只需在mutations函数里改变State值即可。
# 21.Vue-Router 的 Params 和 query 的区别
query: 要用path引入,url 地址类似于ajax中 get 传参,浏览器地址栏显示参数,刷新时 不会 丢失query 里面的数据; params: 要用name引入,utl 地址类似于ajax post 传参,浏览器地址栏不显示参数,刷新时 会 丢失query里面的数据。