Vue面试题总结
一.什么是 VUE?
1.说一下你对vue的理解
vue是一个前端js库,用来动态构建用户界面,采用MVVM模式,重要技术为模板和数据绑定,组件和虚拟DOM
2.如何评价vue
Vue专注于MVVM中的viewmodel层,通过双向数据绑定,把view层和model层连接起来。核心是用数据来驱动DOM。
优点:
- 不需要setState,直接修改数据就能更新视图,而且不需要react的shouldComponentUpdate就能实现高效的Dom渲染。
- 渐进式的开发模式上手会更简单
- html,css,js比react更加优雅的结合在一个文件上
缺点:
指令过多,自带模板不容易拓展,组件数据传递没有react直观和明显
二.Vue生命周期
1.什么是Vue生命周期
Vue实列从创建到销毁的过程,叫做Vue的生命周期。也就是从开始创建,初始化数据,编译模板,挂载DOM——>渲染,更新——>渲染,卸载等一系列过程。
2.Vue生命周期的作用
vue生命周期中有多个事件钩子,他让我们在控制vue实例的过程中更容易形成好的逻辑
3.Vue生命周期总共有几个阶段
共有8个阶段,分别为创建前后,挂载前后,更新前后,销毁前后
4.第一次页面加载会触发哪几个钩子?
beforeCreate, created,beforMount, mounted
5.DOM渲染在哪个周期中就已经完成?
DOM渲染在mounted周期已完成
6.每个生命周期适合哪些场景?
生命周期 | 应用场景 |
---|---|
beforeCreate | 加入loading事件 |
created | 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用 |
mounted | 挂载元素,获取到DOM节点 |
updated | 如果对数据统一处理,在这里写上相应函数 |
beforeDestroy | 可以做一个确认停止事件的确认框 |
nextTick | 更新数据后立即操作dom |
生命周期 | 状态 |
---|---|
beforeCreate | vue实例的挂载元素el和数据对象data都是undefined,还没有初始化 |
created | vue实例的数据对象data有了,可以访问里面的数据和方法,未挂载在DOM,el还没有 |
beforeMount | vue实例的el和data都初始化了,但是挂载之前为虚拟的dom节点 |
mounted | vue实例挂载到真实DOM上,可以通过DOM获取DOM节点 |
beforeUpdate | 响应式数据更新时调用,发生在虚拟DOM打补丁之前,适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器 |
updated | 虚拟DOM重新渲染和打补丁之后调用,组成新的DOM已经更新,避免在这个钩子函数中操作数据,防止死循环 |
beforeDestroy | 实例销毁前调用,还可以用this能获取到实例,常用于销毁定时器,解绑事件 |
destroyed | 实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁 |
三.MVVM和MVC
1.MVVM
M,model代表数据模型,负责保存数据(可以在model中定义数据和操作的业务逻辑)
V,View代表UI组件,她负责将数据模型展现出来。
VM,ViewModel监听数据模型的改变和控制视图行为,处理用户交互,简单来说就是同步view和model的对象
用户操作view层,view数据变化会同步到Model,Model数据变化会立即反应到view中。viewModel通过双向数据绑定把view层和Model层连接了起来
2.MVC
M,Model数据层,用来保存数据
C,controller控制层,负责接收View和用户响应,将数据传递给Model或者从Model中获取数据交给View展现
V,View视图层,负责从controller层获取数据显示数据及响应用户操作
Model和View没有直接通信,都是通过中间人Controller来传递,所以Controller中的负荷越来越重
四,VUE
1.说说你对 SPA 单页面的理解,它的优缺点分别是什么?
SPA是在web页面初始化时加载相应的html,css,js,一旦加载完成,就不会因为用户的操作而进行页面的重新加载和跳转,取而代之的是利用路由机制实现html内容的转换,ui与用户的交互,避免用户的重新加载
优点:
- 用户体验好,速度快,内容的改变不用重新加载整个页面,避免了不必要的跳转和重复渲染
- 单页应用相对于服务器压力小
- 前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理
缺点:
- 初次加载耗时多
- 前进后退路由管理:由于单页应用在一个页面显示所有的内容,所以不能使用浏览器的前进后退功能,所有页面切换需要自己创建堆栈管理
- SEO难度大
2.computed 和 watch 的区别和运用的场景?
区别:
computed是计算属性,它依赖于其他属性,并且computed具有缓存,只有他依赖的属性值发生变化时,下次获取的computed值才会重新计算。
watch,更多的是观察者,是一个监听函数,每当监听的数据变化时都会执行回调函数进行后续操作。
应用场景:
每当我们需要进行数值计算时,并且需要依赖其他属性时,我们应该使用computed,因为我们可以利用computed的缓存特性,避免没次获取值时都需要重新计算
当我们需要在数据发生变化时执行异步操作或者开销较大的操作时,应该使用watch
3.VUE和REACT 的区别?
相似处
功能: 动态构建用户界面
虚拟DOM: 内部都通过虚拟DOM提高效率
组件化: 都使用组件化编程思想编写项目
Props: 组件间通信的基本方式
构建工具: 脚手架, webpack
不同点
界面: JSX与模板
界面更新: 状态管理 与 对象属性监视
数据绑定: 单向与双向
vue的思想是响应式的,也是基于数据可变的,其整体思想仍然是拥抱经典的html,css,js鼓励开发者使用template模板,并提供指令供开发者使用,因此在开发web应用有一种再写经典web应用的感觉
react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,其中组件使用jsx语法,将html,css全都融入js中jsx语法相对比较灵活,当组件调用setState或者props发生变化时,组件内部的render会重新渲染,子组件也会重新渲染。
4.为什么在 Vue3.0 采用了 Proxy,抛弃Object.defineProperty?
Object.defineProperty只能劫持对象的属性,proxy却可以劫持到整个对象并返回一个新对象,proxy不仅可以代理对象,还可以代理数组
proxy优势
- 可以直接监听对象而非属性
- 可以直接监听数组的变化
- 有多达13中拦截方法,这是Object.defineProperty 不具备的;
- proxy返回的是一个新对象,我们可以达到直接操作对象的目的而 Object.defineProperty 只能遍历对象属性直接修改
Object.defineProperty 的优势如下
兼容性好
5.Vue 组件 data 为什么必须是函数
因为组件是可以复用的,js中对象是引用关系,如果data是一个对象,那么就会与子组件中的data值互相污染,产生副作用。当是一个函数时,每个实例可以维护一份被返回对象的独立拷贝
6.谈谈你对 keep-alive 的了解?
keep-alive是vue一个内置的组件,可以是被包含的组件保留状态,防止被重新渲染
7.Vue 中的 key 有什么作用?
key是为vue中vnodel的唯一标识,通过这个key我们可以更加准确、迅速的进行diff操作
8.vue双向绑定底层实现原理
vue.js采用数据劫持的方法,结合发布者订阅者通过object.definepropertty来劫持各个属性的setter,getter以监听数据的变化,在数据变化的时候发布消息给订阅者,触发相应监听回调函数
9.vue 虚拟DOM和react 虚拟DOM的区别
vue虚拟DOM在渲染过程中,会跟踪每一个组件的依赖关系,不需要渲染整个组件树,而对于react来说,当组件的状态改变时,以该组件为根的所有子组件都需要被重新渲染
10.v-show和v-if的区别
v-show的值无论是true还是false,元素都会存在在html代码中,而v-show只有为true时,原素才存在
11.双向绑定和单向数据绑定的优缺点
单向数据绑定优点是,流动方向可以跟踪,流动单一没有状态,这样使得单向绑定能够避免状态管理在复杂度上升时产生的各种问题,程序的调试相对简单,单向数据流更利于状态的维护和优化,更利于组件之间的通信以及组件复用
双向数据流的优点双向绑定在一些需要实时反应用户输入的场合非常方便,用户在视图的修改会自动保存在数据模型中,数据模型中的值也会立刻同步到视图中
缺点:双向数据流是自动管理状态的,但在实际应用中会有很多不得不手动操作状态变化的逻辑,使程序复杂度上升,无法追踪局部状态的变化,同时也导致问题的源头难以被追踪到
双绑跟单向绑定之间的差异只在于,双向绑定把数据变更的操作隐藏在框架内部,调用者并不会直接感知。
12.vue数据代理
通过vm对象来代理data中所有属性的操作,主要是简化vm中的data对象的数据
实现原理:通过Object.defineProperty()给vm添加data对象中的属性,所有添加的属性都有getter/setter,在getter/setter内部操作data中对应的属性数据
五.Vue 组件间通信有哪几种方式?
1.props/$emit适用父子组件通信
2.ref与children 适用父子通信
还可以通过on接收这个消息
3.EventBus (on) 适用于父子,隔代,兄弟组件通信
4.listeners 适用于 隔代组件通信
5.provide / inject 适用于 隔代组件通信
祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。 provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系
6.Vuex 适用于 父子、隔代、兄弟组件通信
7.vue项目中如何如后台通信
- 通过ajax请求与后台通信
- 第三方库 axios
六.VUEX
1.请介绍一下你对vuex的理解?
vuex是一个状态管理模式,对vue应用中多个组件的共享状态进行集中式的管理。每一个vuex应用的核心是store(仓库),它包含着你应用中的大部分状态
vuex的状态存储是响应式的,当vue组件从中读取状态的时候,若store中的状态发生变化,那么相对应的组件也会得到更新
改变store中状态的唯一途径是commit一个mutation
store中主要包括以下几个模块
- State:定义了状态的数据结构,可以在这里设置默认的初始状态
- Getter:允许组件从store中获取状态,相当于计算属性
- Mutation:是唯一更改store中状态的方法,且必须是同步函数
- Action:用于提交mutation,而不是直接变更状态,可以包含任意异步操作
- Module:允许将单一的store拆分成多个store并同时保存到单一的状态树中
七.vue-router
1.请介绍一下你对vue-router的理解
vue-router 有 3 种路由模式:hash、history、abstract
hash模式:在浏览器中符号 ‘#’ 以及后面的字符称之为hash,用window.loaction.hash读取,不会交给服务器端,只在浏览器段使用
history模式: 利用HTML5新特性pushState()/replaceState()及popState事件监听,路径会提交给后台
2.导航守卫
导航守卫是主要功能是监视路由跳转和控制路由跳转
(1)全局导航守卫
- router.beforeEach 全局前置守卫 进入路由之前
- router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用
- router.afterEach 全局后置钩子 进入路由之后
=============================全局前置守卫 ==================================
router.beforeEach((to, from, next) => {
next();
});
=============================全局解析守卫 ==================================
router.beforeResolve((to, from, next) => {
next();
});
=============================全局后置钩子 ==================================
router.afterEach((to, from) => {
console.log('afterEach 全局后置钩子');
})
(2)路由独享的守卫
你可以在路由配置上直接定义 beforeEnter 守卫:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
(3)组件内的守卫
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
next(vm => {
// 通过 `vm` 访问组件实例
})
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
3.vue-router提供了哪些语法
1)一个函数 VueRouter:路由构建函数,用来创建路由对象,配置路由
2)两个对象
$route :代表当前的路由对象,包含当前路由的相关信息(path,params参数,query参数) 后面跟属性
$router :代表路由器对象,包含路由跳转的各种方法(push,replace,back)后面跟方法
3)三个标签
<router-link>: 路由链接, 生成路由链接,相当于a标签
<router-view>: 路由视图, 显示当前路由组件
<keep-alive>: 缓存路由组件对象
本文地址:https://blog.csdn.net/weixin_44331856/article/details/107330579