美文网首页
Vue常见面试题

Vue常见面试题

作者: 小麻烦爱学习 | 来源:发表于2020-10-17 11:40 被阅读0次

8.6.1响应式数据的理解

概述:响应式数据的实现原理是使用ES5的Object.defineProperty,递归遍历对象的属性进行get/set劫持,对数组处理则是劫持了的数组的7个方法(shift/unshift/pop/push/reverse/splice/sort),vue3中则使用ES6的Proxy接口实现数据的响应式
实现细节:每个属性都有一个Dep实例,当调用get方法时,Dep实例收集依赖的watcher.调用set方法时,通知依赖的watcher进行更新
性能优化:1.由于对数据进行劫持的时候,是递归遍历的,所以data的数据最好不要嵌套过深 2.不需要响应的数据不要放到data中 3.对纯展示性的数据可以使用Object.freeze(一个对象如果被freeze,那么将不可被扩展,不可以被重新定义Object.defineProperty)

8.6.2Vue如何检测到数组变化

由于考虑性能原因,没有对数组的每一项进行get/set观测,而是选择重写数组方法的方式
重写了数组的7个会改变原数组的方法,调用新的方法时:1.内部先执行元素的方法,且保存执行结果. 2.判断数组是否有新增的数据,如果有,那么对新增数据进行观测. 3.通知依赖更新
如果通过数组的索引修改值或者修改数组的长度,是无法检测到更新的.可以通过全局方法vue.set达到修改的目的.vue.set内部调用了数组的splice方法.

8.7.1Vue中模板编译原理

  1. 找到template转换成抽象语法树 2. 标记静态节点,优化性能 3.生成代码,用new Function和with语句生成render函数
  2. .vue文件中的template是通过vue-loader进行处理的,vue-loader中的核心模块是vue-template-compiler

8.7.2生命周期钩子是如何实现的

钩子函数就是回调函数.初始化Vue的生命周期时,在选项中配置的生命周期钩子函数会合并到实例的option中.执行到Vue的不同生命周期阶段时,Vue会调options上对应的钩子函数.
内部核心的方法是callHook,采用了发布订阅的设计模式.

8.8.1Vue.mixin的使用场景和原理

使用场景: 全局注入公共的处理逻辑,会影响所有的Vue实例,需谨慎使用
原理: 实例化一个Vue组件时,会把Vue.mixin中的选项和组件中的选项使用合适的策略进行合并.使用了策略模式.
data: 递归遍历每一属性进行合并,冲突时以组件的数据为准
生命周期: 全局和组件的生命周期钩子保存到一个数组,全局的先于组件的执行
其他: 合并为一个对象,冲突时取组件的键值对

8.8.2nextTick使用场景和原理

使用场景: 更新数据后想获取新的dom
原理:
1.Vue内部有一个nextTick方法,该方法接收一个回调作为参数,所有的回调会存入一个回调数组callbacks.这个回调队列是个异步任务队列.Vue2中通过Promise/MutationObserver/setImmediately/setTimeout实现异步.
2.更新数据时,对应的watcher的更新dom的操作会放入callbacks
3.调用nextTick时,回调函数也会放入callbacks 4.同步任务执行完后,清空callbacks队列,由于更新dom在前执行,nextTick的回调后面执行,所以可以获取到最新的dom

8.11.1既然Vue通过数据劫持可以精准检测数据变化,为什么还需要虚拟dom进行diff检测差异?

一个组件对应一个watcher,Vue检测到变化时,会通知当前组件的watcher进行更新.如果不用虚拟dom进行diff差异检测,那么每次有数据变化,整个组件都会更新,对性能影响大.整个过程是:先把范围定位到一个组件,然后定位到dom元素

8.11.1vue中的computed和watch的区别

computed和watch都是Watcher的实例,computed是属性lazy为true的watcher
computed watch
可缓存性 可以 不可以
初始化时取值 不会 会
支持异步 不支持 支持
使用场景 多对一 一对多

8.13.1 Vue组件之间传值的方式及区别

  1. props/emit: 父子组件之间传值
  2. children/ref/parent: 父子组件之间获取实例
  3. attrs/listeners: 祖孙组件之间传值,
  4. provide/inject: 祖孙组件之间通信,主要用于子组件获取父组件的状态.官方文档说不能响应式,通过Vue.Observable()也是可以实现响应式的.
  5. EventBus: 任何组件之间通信,发布订阅模式
  6. Vuex: 任何组件之间通信,中大型项目使用

8.13.2 $attrs是为了解决什么问题出现的?应用场景有哪些?provide/inject不能解决它能解决的问题吗?

  1. $attrs是为了解决当组件嵌套过深,多级组件之间需要一层层传数据的问题
  2. 应用场景:
    ①儿子组件不需要使用爷爷组件的的数据,孙子组件需要使用爷爷组件的数据
    ②儿子组件中获取爸爸组件中非props中传入的数据
  3. 不能.attrs/listeners配合使用,父级组件和孩子组件之间的通信是双向的,而provide/inject父级组件和孩子组件之间的通信是单向的

8.10.1 Vue为什么需要虚拟dom

8.10.2 Vue中diff原理

8.14.1 Vue组件渲染流程

(结合生命周期): 深度优先 递归遍历

  1. new Vue() //this._init()
  2. initLifeCicle/initEvents/initRender
  3. callHooks: beforeCreate
  4. initInject/initState/initProvide
  5. callHooks: created
  6. 找到template编译成render函数:1)template转换成抽象语法树 2)标记静态节点 3)生成字符串代码 4)new Function+ with包裹字符串代码
  7. callHooks: beforeMount
  8. 创建真实节点并挂载:vm._update(vm._render())
    _update: 渲染/更新真实节点,核心方法是patch,里面调用diff算法
    _render: 创建虚拟节点:1)如果是普通dom标签,直接创建元素 2)如果是组件标签,调用Vue.extend给子组件构造一个构造函数且执行构造函数,构造函数的代码:this._init,初始化子组件,且挂载子组件,callHooks:mounted
  9. callHooks:mounted

父子组件的生命周期调用顺序是: 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount-子mounted->父mounted

8.14.1 Vue组件data为什么是一个函数

每次创建组件实例的时候,会调用initData方法,如果data是函数,那么使用函数的返回值;如果是对象,那么返回对象本身.
假如使用对象,对象是引用类型的数据,那么所有的实例会共享同一个对象.而使用函数的话,每次会创建一下新的对象,不会被其他组件实例共享.

8.17.1 Vue-router有几种钩子函数?具体是什么?执行流程是什么样的?

有三类钩子函数:

全局钩子,一般用于权限的控制:
beforeEach: 三个参数to/from/next
beforeResolve:
afterEach: 两个参数to/from
单个路由的钩子,用于对单个路由的逻辑进行处理:
beforeEnter
组件钩子,写在组件里面:
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave

执行流程:

  1. 导航被触发
  2. 失活的组件里面调用beforeRouteLeave
  3. beforeEach
  4. 如果组件可以重用,调用beforeRouteUpdate.
  5. 如果组件不可以重用,beforeEnter
  6. 解析异步路由组件。
  7. beforeRouteEnter
  8. beforeRouteResolve
  9. afterEach
  10. DOM更新
  11. beforeRouterEnter的next回调

8.17.2 vue-router的两种模式的区别

hash模式:地址栏的url会有#,原理:监听hashChange事件

history模式:地址栏的url无#,点击刷新按钮,需要做特殊处理.原理:H5的history接口的pushState方法和popState方法.

8.18.1 函数式组件的优势和原理

函数式组件的优势: 渲染性能高,因为没有响应式数据和生命周期.当一个组件是纯显示不需要响应式数据的情况,或者用来包装组件,可以使用函数式组件
原理: 创建组件的时候,判断functional的值是为true,调用createFunctionalComponent并return,不会执行响应式数据和生命周期的流程

8.18.2 v-if和v-for的优先级

v-for的优先级高于v-if
v-if和v-for不能在同一个元素上使用,因为即使v-if的判断条件为false也会被渲染.更好的处理方式是,v-for之前先对数据做filter处理

8.19.1 组件中写name选项有哪些好处和作用

  1. 使用keep-alive功能时,include和exclude属性中需要匹配组件名称
  2. 组件递归
  3. vue-devtools调试时,有name的组件会显示name,否则显示<AnonymousComponent>

8.19.2 Vue事件修饰符有哪些?其实现原理是什么

事件修饰符有:

.stop:阻止事件冒泡.事件流的3个阶段:捕获阶段/目标阶段/冒泡阶段.
.capture:Vue中绑定的事件默认是在冒泡阶段触发,使用capture修饰符,指定事件在捕获阶段触发
.prevent:阻止事件的默认行为.默认行为:①submit提交后页面刷新②鼠标右击,弹出浏览器默认菜单
.once:监听事件只触发一次
.self:只有触发目标
.passive:不阻止浏览器的默认行为,用来提升移动端的性能.不能和.prevent修饰符一起使用
.native:在组件根元素上监听原生事件

原理:

  1. 把模板编译生抽象语法树时,根据修饰符添加对应的处理方法,核心方法addHandler
  2. 抽象语法树生成代码的时候根据修饰符做生成处理,核心方法genHandler
  3. 根据虚拟节点创建真实节点时绑定事件时做处理,核心方法updateListeners

8.20.1 Vue.directive源码实现

Vue.directive = function (
    id,
    definition
    ) {
    if (!definition) {
        // 如果没有传第二个参数,表示获取指令
        return this.options[type + 's'][id]
    } else {
        // 如果传入的第二个参数是函数,那么绑定到指令的bind和update钩子上
        if (typeof definition === 'function') {
            definition = { bind: definition, update: definition };
        }
        // 如果传入的第二个参数不是函数,直接作为指令的定义
        this.options[type + 's'][id] = definition;
        return definition
    }
};

8.20.2 如何理解自定义指令

当Vue提供的指令无法满足要求,需要对普通dom元素进行底层操作时,考虑使用自定义指令.
指令可以分为全局注册和局部注册
指令有自己的钩子函数:
bind:只调用一次,指令绑定到dom元素时调用
inserted:指令所在的dom插入到父元素时触发,只保证父元素存在,不能保证插入到了文档中
update:所在组件的VNode更新时调用,可能在子VNode更新发生
componentUpdated:所在组件的VNode及其ziVNode都更新后发生
unbind:只调用一次,指令和元素解绑时调用

8.21.1 keep-alive平时在哪使用?原理是?

使用场景:缓存动态组件

使用方法: keep-alive是一个抽象组件,并不会把本身的标签渲染到dom.接收3个参数:include exclude max
include/exclude的值是组件名称,可以用逗号分隔/正则表达式/数组,用来识别哪些组件需要缓存,哪些组件不需要缓存
max:是最大缓存组件的个数,使用LRU(最近最少使用)算法
keep-alive树内的组件的activated/deactivated钩子函数会被触发

原理:

  1. 创建keep-alive组件时,新建一个对象cache,用来缓存动态组件的虚拟节点;新建一个keys数组维护最近使用的组件,max的值用来设置keys数组的最大长度
  2. 渲染的时候,获取插槽的第一个组件孩子的VNode
  3. 判断是否符合include/exclude,如果不符合条件,直接返回
  4. 查找缓存,如果缓存中有,从缓存中拿到组件实例,更新keys数组
  5. 没有缓存中没有,那么放入缓存,更新keys数组
  6. vnode.data.keepAlive = true, 返回vnode

8.21.1 v-if v-model v-for的实现原理

v-if:被解析为一个三目运算符,满足条件调用_c创建vNode的方法,否则返回空节点
v-for:被解析为一个_l(renderList)函数调用,renderList方法返回一个数组,数组的每一项都是以v-for所在元素为模板的render方法
v-model:
1. 和input标签一起使用,被解析为一个指令,输入属性为value,根据input的类型绑定不同的事件:
text/textarea: input事件
select/checkbox/radio: change事件
2. 和自定义组件一起使用:
自定义组件有model对象,包含prop属性和event.v-model绑定的数据会传给prop指定的属性,当组件内部触发event指定的事件时,把emit的值更新到v-model绑定的数据

8.22.1 对vuex的理解

何时应该使用中vuex?中大型的单页面应用,用来管理共享状态时使用vuex.如果项目不大可以使用store模式
原理:
1. 使用Vue.mixin全局混入beforeCreate钩子函数
2. 将store数据挂载到每个vue实例,所以每个组件都可以共享数据
3. Vuex.Store类内部有commit和dispatch方法,分别实现同步和异步修改state

8.22.2 vue中slot是如何实现的?什么时候用它?

插槽分为内容插槽和作用域插槽
内容插槽:父组件向子组件传入内容
作用域插槽: 内容插槽访问子组件的作用域
何时使用:一个组件被使用时,期望显示父组件自定义的内容.换一句话说:实现组件的拓展性.

8.26.1 如何优化单页面首屏加载白屏体验问题?

1.使用路由懒加载
2.骨架屏:先显示页面基本结构,渐进式加载数据
3.服务端渲染首页

8.26.2 vue3.0在响应式方面对vue2.0的主要优化点在哪?

主要优化是数据响应式的方法,2.0是使用ES5的defineProperty,3.0使用的是ES6的Proxy.
defineProperty在数据初始化的时候,递归遍历data对象,给所有的属性增加get/set方法.这种方式的缺点是新增加的属性要手动触发调用Vue.set实现响应式,对数组使用重写方法.
Proxy是对整个data进行懒代理,只有对data的数据进行操作时才会代理,性能高一些;其次对新增属性和数组不必额外处理.

8.27.1 .sync修饰符的作用,用法及原理

作用:用于属性prop的双向绑定
用法:<comp :foo.sync="bar"></comp>
原理:是v-bind+v-on的语法糖,等价于: <com :foo="bar" @update:foo="val => bar = val">

8.27.2 对Vue性能优化的理解

  1. 资源优化:
    生产环境不使用sourcemap(生成环境 devTool:cheap-module-source-map)
    使用路由懒加载
  2. 代码优化:
    对不需要响应式的数据使用Object.freeze
    合理使用v-if/v-show
    在v-for循环的元素上使用:key
    对需要缓存的组件使用keep-alive
    对需要缓存的数据缓存在vuex的store
  3. 用户体验优化:
    移动端事件修饰符使用.passive,不阻止浏览器的默认行为

路由的两种模式?

  1. history模式,刷新后,not found问题如何解决??

相关文章

  • 2021 web高频面试题新人可看

    当日目标 1 常见面试题分布情况? 2 高频面试题 1 常见面试题分布情况 公司面试题一般分为js,vue,小程序...

  • 前端vue面试题分享(附答案)

    本篇文章给大家分享一些常见的前端vue面试题,有一定的参考价值,希望对大家有所帮助。 vue面试题 vue.js的...

  • 关于Vue的一些要点

    参考文章:58 道 Vue 常见面试题集锦,涵盖入门到精通,自测 Vue 掌握程度(Lucky Girl) 文章链...

  • 2020-03-06

    常见前端面试题---vue篇 2、vue生命周期 vue生命周期就是vue实例从创建到销毁的过程。也就是从开始创建...

  • vue面试题之三:vue常见面试题①

    3. vue常见面试题 1. vue的优缺点 优点:性能好,简单易用,前后端分离,双向数据绑定,单页面应用用户体验...

  • Vue性能「二十」-- vue常见面试题

    vue常见面试题整理: 使用及原理篇: 组件间的通讯[https://www.jianshu.com/p/4877...

  • 常见vue面试题

    1. 解释单向数据流和双向数据绑定单向数据流: 数据流是单向的。数据流动方向可以跟踪,流动单一,追查问题的时候可以...

  • Vue必备面试题

    vue常见面试题 1.vue优点? 答:轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十k...

  • 前端面试比较好的文章

    1、前端开发面试题2、vue面试题总汇

  • vue常见面试题

    1.vue优点 2.vue父组件向子组件传递数据? 3.子组件像父组件传递事件 4.v-show和v-...

网友评论

      本文标题:Vue常见面试题

      本文链接:https://www.haomeiwen.com/subject/bdjydktx.html