vue面试题
近期开始总结vue模块的面试题,针对有一定vue基础的同学,希望对你有帮助。之后还会总结vue框架的思想及原理
以及vuex,vue-router等插件源码,请持续关注。
- 请说一下你对响应式数据的理解
核心考察点:数组和对象类型当值变化的时候如何劫持到。对象内部通过
defineReactive方法,使用Object.defineProperty将属性进行劫持(只会劫持已经存在的
属性),数组则是通过重写数组的方法来实现的。这里回答的时候可以带上一些相关的
知识点(比如多层对象是通过递归来进行劫持的,顺带提出Vue3中是使用proxy来实现
响应式数据的,具体的响应式数据的原理会在之后源码解析中解释到)
补充回答:内部的依赖收集是怎么做到的,以及每个属性都会有自己的dep属性,存放
着他所依赖的watcher,当属性变化后会通知自己对应你的watcher去更新。同时也可以谈
及性能优化方面的知识,对象的层级过深,性能就是差、不需要响应数据的内容不需要
放到data中、Object.freeze()可以冻结数据等。
- Vue如何检测数组变化
数组考虑性能原因没有使用defineProperty(他是对数组的每一项进行拦截),而是选择重写数组(push/shift/pop/splice/unshift/sort/reverse)。
补充:在Vue中修改数组索引和长度是无法监控到的。需要通过以上7种变异方法修改数组才会触发数组对应的watcher进行更新。数组中如果是对象数据类型也会进行递归劫持
引发的问题:如果想要更改索引更新数据怎么办?可以通过Vue.$set()来进行处理,内部的核心是splice方法。
- Vue中的模板编译原理
也即是如何将template转换成render函数的(这里需要注意我们开发的时候尽量不要使用template,因为将template转换成render方法需要在运行的时候进行编译操作,会有性能消耗,同时引用带有compiler包的vue体积也会变大。默认.vue文件中的template处理是通过vue-loader来进行处理的并不是通过运行时的编译,默认vue项目中引入的vue.js是不带有compiler模块的)
将tempate模板转换成ast语法树-parseHTML
对静态语法做静态标记
重新生成代码
- 声明周期钩子是如何实现的
Vue的生命周期钩子就是回调函数而已,当创建组件实例的过程中会调用对应的钩子方法,在创建组件实例的过程中会调用对应的钩子方法。
内部主要是使用callHook方法来调用对应的方法。核心是一个发布订阅模式,将钩子订阅好(内部用数组存储),在对应的阶段进行发布。
- Vue.mixin的使用场景和原理
Vue.mixin的作用就是抽离公共的业务逻辑,原理类似“对象的继承”当组件初始化是会调用mergeOptions方法进行合并。如果混入的数据和本身组件中的数据冲突,会此采用就近原则以组件的数据为准。
同时Vue.mixin有很多的缺陷:命名冲突问题、数据来源问题。注意mixin的数据是不会被共享的。
- nextTick的原理和使用场景
- Vue为什么需要使用虚拟dom
- 请说一下Vue中的diff算法的原理
- 既然Vue通过数据劫持可以准确探测数据变化,为什么还要虚拟dom进行diff检测差异
- Vue中computed和watch的区别
- Vue.set如何实现的
- Vue的声明周期方法有哪些?一般在哪一步发起请求以及原因
- Vue组件间传值的方式及之间的区别
- $attrs是为了解决什么问题出现的?应用场景有哪些?provide/inject不能解决他能解决的问题吗?
- Vue组件的渲染流程
- Vue组件的data为什么是一个函数
- 说一下v-if和v-show的区别
- Vue-use是做什么的,原理是什么?
- vue-router有几种钩子函数?具体是什么以及执行流程是怎样的?
- vue-router两种模式的区别
- v-if和v-for的优先级
- 组件中写name选项的好处和作用
- Vue事件修饰符有哪些?其实现原理是什么?
- Vue.directive源码实现
- 如何理解自定义指令?
- 持续添加…