前言
- vue2 面试题(针对一些常问的)
1.说一下computed 和 watch 区别是什么
vue2核心原理(简易)-computed笔记
vue2核心原理(简易)-watch笔记
# 主要考察
1. computed和watch都是基于Watcher来实现的
2. 分别是计算属性watcher和用户watcher。computed属性是具备缓存的, 依赖值不发生变化,
对齐取值时计算属性方法不会重新执行(可以模板渲染, 取值的过程中不支持异步方法)
watch是监控值发生变化, 当值发生变化时调用对应的函数
# 补充回答
1. computed不会立即重新计算生成新的值,而是先标记为脏数据,
当下次computed被获取时候,才会进行重新计算并返回
2. watch则是立即执行, 将老值保存在watcher上, 当数据更新时重新计算新值, 将新值与老值
传递回答函数中
2.说一下响应式数据的理解
Vue2核心原理(简易) - 响应式原理(数据劫持)
# 主要考察:数组和对象是如何劫持到的
1. 对象内部通过defineReactive方法, 使用的是Object.defineProperty将属性进行劫持(只会劫持已经存在的属性, 后续增加的不劫持)
2. 对数组是通过重新写数组的方法实现的(push, pop, unshift, shfit, sort, reverse, splice)
* 可以顺便带出一些相关知识 如多层对象是通过递归实现的, 顺便提一嘴Vue3中是用proxy来实现数据响应的
# 主要考察答出了 也可进行补充回答
1. 内部依赖收集怎么回事 每个属性都拥有自己的dep属性 存放它所依赖的watcher 当属性变化后会通知watcher去更新
2. 每个对象本身也有个dep属性 为了$set
# 这里可以引出性能优化相关内容
1. 对象层级过深 性能就会差
2. 不需要响应的内容不要放到data中
3. Object.freeze() 进行数据冻结(vue将不能对数据进行getter和setter)
3.说一下Vue如何检测数组变化的
Vue2核心原理(简易) - 响应式原理(数据劫持)
# 主要考察
1. 数组考虑性能原因没有用Object.defineProperty进行拦截,
2. 选择重新写数组的七个方法(push, pop, unshift, shfit, sort, reverse, splice)
# 补充回答
1. 所以在Vue中修改数组的索引和长度是无法监控到的, 需要通过以上的7个方法, 去触发数组对应的watcher, 实现更新
2. 如果数组中是对象 会进行递归劫持
# 引发问题
1. 想要通过索引更改数据, 可以通过`Vue.$set()`处理(内部用的splice方法)
4.说一下模板编译原理
Vue2核心原理(简易) - 模板编译(笔记)
# 主要考察
1. 如何将template转换成render函数(这里要说明的是我们在开发时尽量不要使用template, 因为将template转换成render方法, 需要在运行时进行编译操作会有性能消耗
同时引用带有compiler包vue的体积也会变大, 默认的.vue文件中的template处理是通过vue-loader进行处理, 并不是通过运行时编译)
* 1.将template模板转换成ast语法树 - parserHTML方法
* 2.对静态语法做静态标记 - markUp方法
* 3.重新生成代码 - codeGen方法
# 补充回答
1. 模板引擎的实现原理就是new Function + with
2. vue-loader中处理template属性主要考的是vue-template-compiler模块
* const VueTemplateCompiler = require('vue-template-compiler')
* const { render } = VueTemplateCompiler.compile('<div id="hello">{{msg}}</div>')
5.说一下生命周期钩子是如何实现的
vue2核心原理(简易) - 生命周期初次实现 + Vue.mixin笔记
# 主要考察
1. 生命周期钩子 就是回掉函数, 在创建组件实例的过程中去调用对应的钩子方法
# 补充回答
1. 内部主要使用callHook方法去调用对应的方法(核心是个发布订阅模式), 将钩子订阅好(内部采用数组的方式存储), 然后在对应得阶段进行发布
6.说一下Vue.mixin()的使用场景和原理
vue2核心原理(简易) - 生命周期初次实现 + Vue.mixin笔记
# 主要考察(原理)
1. Vue.mixin(options), 将Vue本身的options, 和后期用户传入的options, 递归混合
2. 针对不同类型的options(options.key不同), 采用不同的策略(列队存储, 递归继承等)
3. 这些策略放在一个存储空间 strats = {}
4. 如果strats中存在对应的key策略, 就直接执行该策略, 然后返回即可
如果不存在, 就父组件(Vue.options对应的key)与子组件(options)进行合并 都有的情况下, 子覆盖父
5. 最后将父子options对应的key都执行了一遍 实现了混合策略
# 主要考察(场景)
1. 父子组件的生命周期就是采用Vue.mixin()方法将每次混入的钩子函数按照顺序都放在一个队列当中, 当触发条件时 依次执行
2. 父子组件的混合(Vue.componet), 根据父对象构建一个新的对象(Object.create(parent.options.componet)), 新对象就继承了父对象的proto,
然后将新对象依次赋予options[key] = childOptins[key], 这样如果自身没有值 就可以在父组件找到对应的值
7.说一下nextTick使用场景和原理
vue2核心原理(简易)-异步更新(Vue.nextTick)笔记
# 主要考察(场景原理)
1. nextTick中的回调是下次DOM更新循环结束之后执行的延迟回调,在修改数据之后立即使用这个方法,获取更新后的DOM
2.原理就是异步方法(如promise mutationObserver,setimmediate,setTimeout)经常与事件一起来问(宏任务和微任务)
# 补充回答
1. vue多次更新数据 最终会进行批处理更新 内部调用的就是nextTick实现了延迟更新,用户自定义的nextTick中的回调会被延迟到更新完成后调用, 从而实现更新后的DOM
8.说一下为什么需要虚拟DOM
vue2核心原理(简易) - diff算法解析笔记
# 主要考察(场景原理)
1. Virtual DOM就是用js对象来描述真实DOM, 是对真实DOM的抽象,由于直接DOM的抽象, 由于直接操作DOM性能低但是js层的操作效率高,可以将DOM操作转化成对象操作
2. 最终通过diff算法比对差异进行更新DOM, 减少了对真实DOM的操作, 虚拟DOM不依赖真实平台环境,虚拟DOM不依赖真实平台环境从而也可以实现跨平台
# 补充回答
1. 虚拟DOM的实现就是普通对象包含tag, attrs, children等属性对真实节点的描述,本质上就是在JS和DOM之间的缓存
9.说一下diff的原理
vue2核心原理(简易) - diff算法解析笔记
# 主要考察
1. Vue中的diff算法是平级比较, 不考虑跨级比较的情况, 内部采用深度递归的方式 + 双指针的方式进行比较
* 首先比较是相同的节点 不是直接替换掉
* 相同的节点比较属性 并复用老节点
* 比较儿子节点 考虑老节点和新节点儿子情况
* 优化比较: 头头比较 尾尾比较 头尾比较 尾头比较
* 比对查找进行复用
# 补充回答
1. Vue3中采用最长递增子序列实现diff算法
10.说一下既然Vue通过数据劫持可以精准探测数据变化 为什么还需要虚拟DOM进行diff检测差异
vue2核心原理(简易) - diff算法解析笔记
# 主要考察
1. 响应式数据变化 Vue确实可以在数据发生变化时 响应式系统可以立刻得知, 但如果给每个属性都添加watcher用于更新的话,
会产生大量的watcher从而降低性能,而且力度过细也会导致不精准的问题 所以Vue采用组件级的watcher配合diff来检测差异
2. 可以往diff算法说说
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!