vue面试题分享
9月23号
1、Vue解决了什么问题
- vue 用虚拟dom解决了真实dom带来的笨重操作 提高了性能
- 并把结构 样式和逻辑分离 用mvvm的原理实现便捷开发 提升开发效率
- 把一个个功能写成一个个组件 便于开发
2、MVVM的理解
MVVM就是Model-View-ViewModel的缩写 model处理数据,view处理视图,vm用来将数据和视图中互相转换,既将数据显示在视图,将视图触发事件反应给数据
3、为什么 data 是一个函数
因为data为了给组件开辟私有空间 从而不影响多个组件的数据 而函数刚好是唯一的局部作用域 不会被外面影响 这样可以让各个组件维护各自的数据
4、v-if 与 v-for 为什么不建议一起使用
因为有优先级 在vue2中 v-for优先级高于v-if 所以会先解析v-for vue3刚好相反
5、谈谈你对 Vue 生命周期的理解?
vue生命周期就像人的一生 从出生 上学 成家 死亡的经历
常用的一共有八个生命周期 顺序是
创建前beforeCreate 创建后Create 挂载前beforeMount 挂载后mounted 更新前beforeUpdate 更新后update 卸载前beforeDestory 卸载后destoryed
| 生命周期 | 描述 |
|---|---|
| beforeCreate | 创建前 无render和el节点 |
| created | 创建后 无render和el节点 |
| beforeMount | 挂载前 相关的 render 函数首次被调用 此时el还没上树 |
| mounted | 挂载后 el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子 |
| beforeUpdate | 更新前 |
| update | 更新后 |
| beforeDestory | 卸载前 |
| destoryed | 卸载后 |
6、Vue-router 路由模式有几种?
两种 "hash" 和 "history"
7、在哪个生命周期内调用异步请求?
可以在created beforeMount mounted三个生命周期调用 因为在这三个生命周期钩子data已经创建了 可以把后端返回的数据进行赋值 但是更推荐在created里调用
原因有二
1.能更快获取到服务端数据 减少longing时间
2,服务器端渲染不支持 beforeMount 、mounted 钩子函数,为了和服务器时间一致 所以推荐使用created
8、说说你对 SPA 单页面的理解,它的优缺点分别是什么?
SPA是单页面应用 所谓的单页面应用 就是不会因为用户的操作而进行页面的重新加载或跳转 从而加载或跳转另一个网页 取而代之的是用路由来切换页面 避免页面重新加载
优点
- 用户的体验好、 加载速度快 内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染
- 基于上面一点,SPA 相对对服务器压力小
- 前后端分离开发 各干各的 前端页面展示 后端数据处理
缺点
- 初次加载比较久 因为初次渲染页面要把html css js还有一些第三方的包一并加载
- 前进后退难管理 由于单页页面在浏览器上显示所有内容 所以不能使用浏览器的前进后退功能 所有的页面都要进行堆栈管理 会遇到后退两次 前进一次就回到当前页面的bug
- seo(搜索引擎)难以优化 因为切换页面太多
9、v-show 与 v-if 有什么区别?
v-if是条件编译 当条件的结果为true是渲染页面内容 而结果为false是不会渲染页面 什么都不做
v-show的true是显示 false是隐藏 v-show的隐藏时display是为none
因此v-if适合切换不多 很少改变条件的使用场景 例如登录注册页面 v-show则适用于需要频繁切换的使用场景 例如tab切换
9月24号
1、Vue 的父组件和子组件生命周期钩子函数执行顺序?
Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下 4 部分:
加载渲染过程
父 创建前-> 父 创建后 -> 父 挂载前 -> 子 创建前 -> 子 创建后 -> 子 挂载前 -> 子 挂载后 ->父 挂载后
子组件更新过程
父 更新前->子 更新前->子 更新后 -> 父更新后
父组件更新过程
父 更新前 -> 父更新后
销毁过程
父 卸载前 -> 子 卸载前 -> 子卸载后 -> 父卸载后 \
2、Class 与 Style 如何动态绑定?
Class 可以通过对象语法和数组语法进行动态绑定:
- 对象语法:
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
data: {
isActive: true,
hasError: false
}
- 数组语法:
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
Style 也可以通过对象语法和数组语法进行动态绑定:
- 对象语法:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
- 数组语法:
<div v-bind:style="[styleColor, styleSize]"></div>
data: {
styleColor: {
color: 'red'
},
styleSize:{
fontSize:'23px'
}
}
3 怎样理解 Vue 的单向数据流?
所有的prop都是父传子 以父组件的数据用prop传入子组件 而子组件的数据无法传到父组件 这是因为防止子组件的数据更新影响到父组件
而子组件想要传数据到父组件 则要通过$emit 派发一个自定义事件 父组件接收到后,由父组件修改。
有两种常见的试图改变一个 prop 的情形 :
这个 prop用来传递一个初始值 子组件希望把这个初始值作为自己的数据使用 所以放在本地的 data 属性并将这个 prop 用作其初始值
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
当这个 prop 以一种原始的值传入且需要进行转换 便用计算属性来转换\
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
4、computed 和 watch 的区别和运用的场景?
computed是计算属性 就是函数里面返回的是处理过的数据 使用起来像变量 并且 computed 的值有缓存
watch是倾听器 更多的是监听数据变化 每当监听到数据变化 就会进行回调进行后续操作
运用场景
计算属性的使用场景是进行数值计算 并且要依赖于别的数据时 才会使用computed 因为computed有缓存机制 所以可以避免每次获取值时,都要重新计算
当我们需要在数据变化时执行异步或开销较大的操作时,例如搜索框输入内容 监听路由 要监听数据改变 此时就要使用watch 并可以获取每一步的变化的数据
5、在什么阶段才能访问操作DOM?
在钩子函数 mounted 被调用前,Vue 已经将编译好的模板挂载到页面上,所以在 mounted 中可以访问操作 DOM
6、直接给一个数组项赋值,Vue 能检测到变化吗?
由于js的类型限制 Vue 不能检测到以下数组的变动
- 当你利用索引直接设置一个数组项时,例如:
vm.items[indexOfItem] = newValue - 当你修改数组的长度时,例如:
vm.items.length = newLength
为了解决第一个问题,Vue 提供了以下操作方法:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// vm.$set,Vue.set的一个别名
vm.$set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
为了解决第二个问题,Vue 提供了以下操作方法
// Array.prototype.splice
vm.items.splice(newLength)
7、你使用过 Vuex 吗?
vuex是专门为vue设计的数据共享状态 用来解决复杂的数据传信 每一个vuex的核心就是store 每一个store就像一个仓库 保存了应用中大部分的状态(state)
state
存数据的地方,所有的数据都要存在state里面 类似于vue中的data
Actions
Action 提交的是 mutation,而不是直接变更状态。 Action 可以包含任意异步操作。
mutation
它是唯一能更改 store 中状态的方法,且必须是同步函数。
Getter
store中的计算属性 让组件从 Store 中获取处理过的数据 mapGetters 辅助函数仅仅是把store里面的getter映射到局部计算属性
Module
module类似于模块化 允许将单个的store拆分成多个store进行管理
8、Vue 组件间通信有哪几种方式?
第一种 props / $emit 适用 父子组件通信
父组件向子组件传递数据,通过prop传递。子组件传递数据给父组件是通过emit事件
第二种 vuex 适合父子 兄弟 隔代组件通信
vuex是专门为vue设计的数据共享状态 用来解决复杂的数据传信 每一个vuex的核心就是store 每一个store就像一个仓库 保存了应用中大部分的状态(state)
第三种 EventBus 适合父子 兄弟 隔代组件通信
EventBus是通过创建一个空的vue实例作为中央事件总线 每次组件通信都通过它来触发事件和监听事件 类似买房时的中介
第四种 $ref获取实例
$ref如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例