写这篇文章的原因是想好好把vue复习一下,然后整理一下我认为常见很重要的面试题,也方便我自己以后查阅,我觉得这些基本上是Vue里面相关的所有重要知识点了,相信会对现在找工作的小伙伴们很大帮助!
大家可以先看一下这个提纲思考下,看看自己还有哪些不清楚的地方,查漏补缺一下~~~
MVVM
原理的理解Vue
采用异步渲染vue
优点Proxy
与Object.defineProperty()
的对比React
和Vue
Vue
中相同逻辑如何抽离nextTick
实现原理diff
算法的时间复杂度Vue
中diff
算法原理Vue
中v-if
和v-show
的区别Vue
每个生命周期什么时候被调用v-for
和v-if
不能连用Vue
如何进行组件间的通信beforeDestroy
keep-alive
的了解v-for
中为什么要用key
data
为什么是函数computed
和watch
有什么区别vue
几种常用的指令vue
常用的修饰符Vue
的渲染过程vue
中的模板编译原理Vue
中v-html
会导致哪些问题dom
的绑定Watch
中的deep:true
是如何实现的action
和mutation
区别vue-router
有哪几种导航钩子hash
路由和history
路由$route
和 $router
的区别Vuex
的理解及使用场景Vue
项目进行哪些优化Vue3.0
你知道有哪些改进M - Model,Model
代表数据模型,也可以在Model
中定义数据修改和操作的业务逻辑
V - View,View
代表 UI
组件,它负责将数据模型转化为 UI
展现出来
VM - ViewModel,ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步 View
和 Model
的对象,连接 Model
和 View
【重点】:一定要理解Vue
的MVVM
原理,面试必问!
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()
来劫持各个属性的setter
,getter
默认Vue在初始化数据时,会给data
中的属性使用Object.defineProperty
重新定义所有属性,当页面到对应属性时,会进行依赖收集(收集当前组件中的watcher
)如果属性发生变化会通知相关依赖进行更新操作
因为如果不采用异步更新,那么每次更新数据都会对当前租金按进行重新渲染,所以为了性能考虑,Vue
会在本轮数据更新后,再去异步更新数据
Vue.js
通过简洁的API提供高效的数据绑定和灵活的组件系统MVVM
思想实现数据的双向绑定,让开发者不用再操作dom
对象,有更多的时间去思考业务逻辑Vue.js
通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件(component
)中,我们只要先在父级应用中写好各种组件标签(占坑),并且在组件标签中写好要传入组件的参数(就像给函数传入参数一样,这个参数叫做组件的属性),然后再分别写好各种组件的实现(填坑),然后整个应用就算做完了DOM
操作计算出来并优化,由于这个DOM
操作属于预处理操作,并没有真实的操作DOM
,所以叫做虚拟DOM
。最后在计算完毕才真正将DOM
操作提交,将DOM
操作变化反映到DOM
树上react
而言,同样都是操作虚拟dom
,就性能而言,vue
存在很大的优势Proxy的优点:
Proxy的缺点:
Proxy
是es6
提供的新特性,兼容性不好,所以导致Vue3一致没有正式发布让开发者使用Object.defineProperty的优点:
Object.defineProperty的缺点:
监听数据变化的实现原理不同:
Vue
通过getter/sette
r以及一些函数,能精确知道数据变化React
默认是通过比较引用的方式(diff
)进行的,React
不精确监听数据变化数据流不同:
Vue2.0
可以通过props
实现双向绑定,用vuex
单向数据流的状态管理框架React
不支持双向绑定,提倡单项数据流,Redux
单向数据流的状态管理框架组件通信的区别:
props
向子组件传递数据或回调event
向父组件发送数据或回调provide/inject
实现父组件向子组件传入数据,可跨层级props
向子组件传递数据React
不支持子组件像父组件发送数据,而使用的是回调函数context
实现父组件向子组件传入数据, 可跨层级模板渲染方式不同:
React
通过JSX
渲染模板Vue
通过HTML
进行渲染React
是通过原生JS
实现模板中常见语法,如:插件,条件,循环Vue
是与组件JS
分离的单独模板,通过指令实现,如:v-if
模板中使用的数据:
React
里模板中使用的数据可以直接import
的组件在render
中调用Vue
里模板中使用的数据必须要在this
上进行中转,还要import
一个组件,还要在components
中声明渲染过程不同:
Vue
不需要渲染整个组件树React
状态改变时,全部子组件重新渲染框架本质不同:
Vue
本质是MVVM
框架,由MVC
发展而来React
是前端组件化框架,由后端组件化发展而来Vuex和Redux的区别:
Vuex
可以使用dispatch
、commit
提交更新Redux
只能用dispatch
提交更新组合不同功能方式不同:
Vue
组合不同功能方式是通过mixin
,可以帮我定义的模板进行编译、声明的props
接收到数据….React
组合不同功能方式是通过HoC
(高阶组件),本质是高阶函数Vue.mixin
用法给组件每个生命周期,函数等都混入一些公共逻辑
nextTick
方法主要是使用了宏任务和微任务,定义一个异步方法,多次调用nextTick
会将方法存在队列中,通过这个异步方法清空当前队列。所以这个nextTick
方法就是异步方法
两个数的完全的diff
算法是一个时间复杂度为o(n3)
, Vue
进行了优化O(n3)
复杂度的问题转换成O(n)
复杂度的问题(只比较同级不考虑跨级问题)在前端当中,你很少会跨级层级地移动Dom
元素,所以Virtual Dom
只会对同一个层级地元素进行对比
(大家要是不懂也可以看下这篇文章)对Dom-Diff的理解
v-show
是css
切换,v-if
是完整的销毁和重新创建
使用 频繁切换时用v-show
,运行时较少改变时用v-if
v-if=‘false’
v-if
是条件渲染,当false
的时候不会渲染
beforeCreate
在实例初始化之后,数据观测(data observer
)之前被调用created
实例已经创建完成之后被调用,在这一步,完成已完成以下的配置:数据观测(data observer
),属性和方法的运算,watch/event
事件回调,这里没有$el
beforeMount
在挂载开始之前被调用:相关的render
函数首次被调用mounted el
被创建的vm.$el
替换,并挂载到实例上去之后调用该钩子beforeUpdate
数据更新时调用,发生虚拟DOM
重新渲染和补丁之前updated
由于数据更改导致的虚拟DOM
重新渲染和打补丁,在这之后调用该钩子beforeDestory
实例销毁之前调用,在这一步,实例仍然完全可用destroyed
Vue
实例销毁后调用,调用后,Vu
实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用异步请求是在mounted
生命周期中调用的,而实际上也可以在created
生命周期中调用
beforeCreate, created, beforeMount, mounted
当 v-for
和 v-if
处于同一个节点时,v-for
的优先级比 v-if
更高,这意味着 v-if
将分别重复运行于每个 v-for
循环中。如果要遍历的数组很大,而真正要展示的数据很少时,这将造成很大的性能浪费。 这种场景建议使用 computed
,先对数据进行过滤
父向子传递数据通过props
子向父传递是通过$emit
、event
子实例访问父实例通过$parent
父实例访问子实例通过$children
$attrs
用父组件传递数据给子组件或孙组件 (包含了父作用域中不作为 prop
被识别 (且获取) 的特性绑定 (class
和 style
除外))
listeners用父组件传递数据给子组件或孙组件 包含了父作用域中的 (不含 .native
修饰器的)v-on
事件监听器
祖先组件通过provider
提供变量给子孙组件
子孙组件通过inject
注入变量给祖先组件
ref
用来访问组件实例
vuex
用来作为兄弟之间和跨级之间的通信
vuex
用来作为兄弟之间和跨级之间的通信
$attrs
用父组件传递数据给子组件或孙组件 (包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class
和 style
除外))
listeners用父组件传递数据给子组件或孙组件 包含了父作用域中的 (不含 .native
修饰器的) v-on
事件监听器
祖先组件通过provider
提供变量给子孙组件
子孙组件通过inject
注入变量给祖先组件
(大家要是还不清楚可以看下这篇文章)
彻底理解Vue组件间通信(6种方式)-完整版
$on
方法,那需要在组件销毁前解绑srcoll
mousemove
....单个插槽:
当子组件模板只有一个没有属性的插槽时, 父组件传入的整个内容片段将插入到插槽所在的 DOM
位置, 并替换掉插槽标签本身
命名插槽:
solt
元素可以用一个特殊的特性name
来进一步配置如何分发内容。 多个插槽可以有不同的名字。 这样可以将父组件模板中 slot
位置, 和子组件slot
元素产生关联,便于插槽内容对应传递
作用域插槽:
可以访问组件内部数据的可复用插槽(reusable slot)
在父级中,具有特殊特性 slot-scope
的元素必须存在, 表示它是作用域插槽的模板。
slot-scope
的值将被用作一个临时变量名, 此变量接收从子组件传递过来的 prop
对象
keep-alive
是 Vue
内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 。它拥有两个独立的生命周期钩子函数 actived
和 deactived
,使用 keep-alive
包裹的组件在切换时不会被销毁,而是缓存到内存中并执行 deactived
钩子函数,命中缓存渲染后会执行actived
钩子函数
key
是为Vue
中的vnode
标记的唯一id
,通过这个key
,我们的diff
操作可以 更准确、更快速
准确:
如果不加key
,那么vue
会选择复用节点(Vue
的就地更新策略),导致之前节点的状态被保留下来,会产生一系列的bug
快速:
key
的唯一性可以被Map
数据结构充分利用
因为组件是用来复用的,JS
里对象是引用关系,这样作用域没有隔离,而new
Vue
的实例,是不会被复用的,因此不存在引用对象问题
计算属性是基于他们的响应式依赖进行缓存的,只有在依赖发生变化时,才会计算求值,而使用 methods
,每次都会执行相应的方法
v-for
、 v-if
、v-bind
、v-on
、v-show
、v-else
.prevent
: 提交事件不再重载页面.stop
: 阻止单击事件冒泡.self
: 当事件发生在该元素本身而不是子元素的时候会触发.capture
: 事件侦听,事件发生的时候会调用1、把模板编译为render
函数
2、实例进行挂载, 根据根节点render
函数的调用,递归的生成虚拟dom
3、对比虚拟dom
,渲染到真实dom
4、组件内部data
发生变化,组件和子组件引用data
作为props
重新调用render
函数,生成虚拟dom
, 返回到步骤3
template
转化成render
函数xss
攻击v-html
会替换掉标签内部的子元素vue
在创建真是dom
时会调用createElm
,默认会调用invokeCreateHooks
会遍历当前平台下相对的属性处理代码,其中就有updateDOMListeners
方法,内部会传入add
方法
vue
中绑定事件是直接绑定给真实dom
元素的
组件绑定事件是通过vue
中自定义的$on
方法来实现的
当用户指定了watch
中的deep
属性为true
时,如果当前监控的值是数组类型,会对对象中的每一项进行求值,此时会将当前watcher
存入到对应属性的依赖中,这样数组中的对象发生变化时也会通知数据更新
mutation
是同步更新数据(内部会进行是否为异步方式更新数据的检测)action
异步操作,可以获取数据后调用mutation
提交最终数据有3种
router.beforeEach(to,from,next)
,作用:跳转前进行判断拦截$route
和$router
的区别router
为VueRouter
的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象 经常用的跳转链接就可以用this.$router.push
,和router-link
跳转一样
$route为当前router跳转对象里面可以获取name
、path
、query
、params
等
Vuex
是一个专为 Vue
应用程序开发的状态管理模式。每一个 Vuex
应用的核心就是 store(仓库)
Vuex
主要包括以下几个核心模块:
State
:定义了应用的状态数据
Getter
:在 store
中定义“getter
”(可以认为是 store
的计算属性),就像计算属性一样,getter
的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
Mutation
:是唯一更改 store
中状态的方法,且必须是同步函数
Action
:用于提交 mutation
,而不是直接变更状态,可以包含任意异步操作
Module
:允许将单一的 Store
拆分为多个 store
且同时保存在单一的状态树中
代码层面的优化:
v-if
和 v-show
区分使用场景computed
和watch
区分使用场景v-for
遍历必须为 item
添加 key
,且避免同时使用 v-if
SSR or
预渲染Webpack 层面的优化:
Webpack
对图片进行压缩ES6
转为 ES5
的冗余代码CSS
SourceMap
基础的 Web
技术的优化:
1.开启gzip
压缩
2.浏览器缓存
3.CDN
的使用
4.使用 Chrome Performance
查找性能瓶颈
Vue3
采用了TS
来编写Composition API
Vue3
中响应式数据原理改成proxy
vdom
的对比算法更新,只更新vdom
的绑定了动态数据的部分在大型应用中,功能不停地累加后,核心页面已经不堪重负,访问速度愈来愈慢。为了解决这个问题我们需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块,从而提高页面加载速度
我认为的vue比较重要的就这么多了吧,要是大家有更好的欢迎在评论区补充,最后祝大家找到自己满意的工作~~~
关注公众号即可加我好友,我拉你进 前端交流群,大家一起共同交流和进步❤️❤️❤️