Vue面试题汇总
1.首先谈谈你对Vue的理解
关键点:渐进式 JavaScript框架、核心库加插件、动态创建用户界面(异步获取后台数据,数据展示在界面)
特点:MVVM模式;代码简洁体积小,运行效率高,适合移动PC端开发;本
身只关注 UI (和react似),可以轻松引入Vue插件或其他的第三方库进行开发。
2.什么是MVVM
view依然是我们的dom(视图层)
model就是我们抽离出来的obj(数据模型层)
viewModel就是我们创建的view实列
它们之间是如何工作:
先viewModel通过Data Binding让obj重的数据实时的DOM重显示,其次ViewModel通过DOM Linstener来监听DOM事件,
并通过Methods中的操作,来改变obj的数据。
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过--Object.defineProperty()来劫持
各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
3.组件的key属性
官方推荐我们使用v-for的时候,给对应的元素添加key属性,目的是为了让我们更好的复用,
需要使用key来给每个节点做一个唯一标识,key的主要作用就是为了高效的更新虚拟DOM
4.说下对Vue生命周期的理解
*创建前/后:在beforeCreate阶段,vue实例的挂载el和数据对象data都为undefined,还未初始化。
在created阶段,vue实例的数据对象有了data,el为undefined,还未初始化
*载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但是挂载之前为虚拟dom的节点,
data.message还未替换,在mounted阶段,vue实例挂载完成,data.message成功渲染
*更新前/后:当data变化时,会触发beforeUpdate和updated方法
*销毁前/后:在执行destory方法后,对data的改变不会再触发周期函数,
说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在
5.Vue中v-if和v-show区别
- `v-if` 如果条件不成立不会渲染当前指令所在节点的DOM元素
- `v-show` 只是切换当前DOM的显示与隐藏
- **性能消耗**:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;
- **使用场景**:v-if适合运营条件不大可能改变;v-show适合频繁切换。
6.计算属性computed和侦听属性watch的区别
**computed**:默认`computed`也是一个`watcher`具备缓存,只有当依赖的数据变化时才会计算,
当数据没有变化时, 它会读取缓存数据。如果一个数据依赖于其他数据,使用` computed `
**watch**:每次都需要执行函数。 `watch` 更适用于数据变化时的异步操作。
如果需要在某个数据变化时做一些事情,使用watch。
**method**:只要把方法用到模板上了,每次一变化就会重新渲染视图,性能开销大
使用场景:`computed`:当一个属性受多个属性影响的时候使用,例:购物车商品结算功能
`watch`:当一条数据影响多条数据的时候使用,例:搜索数据
7.常用的事件修饰符
- .stop:阻止冒泡
- .prevent:阻止默认行为
- .self:仅绑定元素自身触发
- .once:只触发一次
- passive:滚动事件的默认行为 (即滚动行为) 将会立即触发,不能和.prevent 一起使用
-.sync 修饰符
8.vue如何获取dom
先给标签设置一个ref值,再通过this.$refs.domName获取,
eg:<div ref="test"></div>
const dom =this.$refs.test
9.solt插槽
很多时候,我们封装了一个子组件之后,在父组件使用的时候,想添加一些dom元素,
这个时候就可以使用slot插槽了,但是这些dom是否显示以及在哪里显示,则是看子组件中slot组件的位置了
10.v-model中的实现原理及如何自定义v-model
v-mode可以看成是 value+input方法的语法糖(组件)。
原生的v-model ,会根据标签的不同生成不同的事件与属性。解析一个指令来。
自定义:自己写model属性,里面放上 prop和 event
11.Vue组件通信
- 父子间通信:父亲提供数据通过属性` props `传给儿子;儿子通过` $on ` 绑父亲的事件,
再通过` $emit ` 触发自己的事件(发布订阅)
- 利用父子关系` $parent ` 、` $children ` ,
获取父子组件实例的方法。
- 父组件提供数据,子组件注入。` provide ` 、` inject ` ,插件用得多。
- `ref` 获取组件实例,调用组件的属性、方法
- 跨组件通信` Event Bus ` (Vue.prototype.bus=newVue)其实基于bus = new Vue)其实基于bus=newVue)其实基于on与$emit
- `vuex` 状态管理实现通信
12.Vue性能优化
**编码优化**:
- 事件代理
- keep-alive
- 拆分组件
- key保证唯一性
- 路由懒加载、异步组件
- 防抖节流
**Vue加载性能优化**
- 第三方模块按需导入(babel-plugin-component)
- 图片懒加载
**SEO优化**
- 预渲染
13.了解nextTick吗?
异步方法,异步渲染最后一步,与JS事件循环联系紧密。
主要使用了宏任务微任务(`setTimeout`、`promise`那些),定义了一个异步方法,
多次调用`nextTick`会将方法存入队列,通过异步方法清空当前队列。
14.组件中data为什么是函数
避免组件中的数据互相影响。同一个组件被复用多次会创建多个实例,
如果` data` 是一个对象的话,这些实例用的是同一个构造函数。
为了保证组件的数据独立,要求每个组件都必须通过` data` 函数返回一个对象作为组件的状态
15.什么是事件代理(事件委托),有什么好处
事件委托的原理:不给每个子节点单独设置事件监听器,而是设置在其父节点上,
然后利用冒泡原理设置每个子节点。
好处:减少内存消耗和dom操作,提高性能,
16.什么是webpack
webpack是一个现代的JavaScript应用的静态模块打包工具
17.keep-alive
keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,或者避免重新渲染
router-view也是一个组件,如果直接被包在keep-alive里面,所有路径匹配到的组件都会被缓存
使用keep-alive的时候,组件不会被频繁的创建和销毁(可以排除一些组件),被排除的组件还是会被频繁创建和销毁
//`keep-alive` 可以实现组件的缓存,当组件切换时不会对当前组件进行卸载。
常用的2个属性` include/exclude` ,2个生命周期` activated` ,` deactivated`
Vuex(状态管理器)
Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
**vuex中五大核心属性,分别是什么?
- state 唯一数据源,Vue 实例中的 data 遵循相同的规则
- getters 可以认为是 store 的计算属性,就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,
且只有当它的依赖值发生了改变才会被重新计算。Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值.
- mutation 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,非常类似于事件,通过store.commit 方法触发
- action Action 类似于 mutation,不同在于Action 提交的是 mutation,而不是直接变更状态,
Action 可以包含任意异步操作
- module 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。
当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。
3. Vuex 和 localStorage 的区别
(1)最重要的区别
- vuex存储在内存中
- localstorage 则以文件的方式存储在本地,只能存储字符串类型的数据,存储对象需要 JSON的stringify和parse方法进行处理。 读取内存比读取硬盘速度要快
(2)应用场景
- Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。vuex用于组件之间的传值。
- localstorage是本地存储,是将数据存储到浏览器的方法,一般是在跨页面传递数据时使用 。
- Vuex能做到数据的响应式,localstorage不能
(3)永久性
刷新页面时vuex存储的值会丢失,localstorage不会。
注意: 对于不变的数据确实可以用localstorage可以代替vuex,但是当两个组件共用一个数据源(对象或数组)时,如果其中一个组件改变了该数据源,希望另一个组件响应该变化时,localstorage无法做到,原因就是区别1。
Vue-router
**怎么定义vue-router的动态路由?怎么获取传过来的动态参数?
在router目录下的index.js文件中,对path属性加上/:id。 使用router对象的params.id获取动态参数
**vue-router的导航钩子 比如最常见的登录权限验证, 常用的是router.beforeEach(to,from,next),在跳转前进行权限判断。一共有三种:
- 全局导航钩子:router.beforeEach(to,from,next)
- 组件内的钩子
- 单独路由独享组件
vue路由传参
使用query方法传入的参数使用this.$route.query接受
使用params方式传入的参数使用this.$route.params接受
router和route的区别
route为当前router跳转对象里面可以获取name、path、query、params等
router为VueRouter实例,想要导航到不同URL,则使用router.push方法