为什么要使用异步组件
- 节省打包出的结果,异步组件分开打包,采用
jsonp的方式进行加载,有效解决文件过大的问题。 - 核心就是包组件定义变成一个函数,依赖
import()语法,可以实现文件的分割加载。
components:{
AddCustomerSchedule:(resolve)=>import("../components/AddCustomer") // require([])
}
原理
export function ( Ctor: Class<Component> | Function | Object | void, data: ?VNodeData, context: Component, children: ?Array<VNode>, tag?: string ): VNode | Array<VNode> | void {
// async component
let asyncFactory
if (isUndef(Ctor.cid)) {
asyncFactory = Ctor
Ctor = resolveAsyncComponent(asyncFactory, baseCtor) // 默认调用此函数时返回 undefiend
// 第二次渲染时Ctor不为undefined
if (Ctor === undefined) {
return createAsyncPlaceholder( // 渲染占位符 空虚拟节点
asyncFactory,
data,
context,
children,
tag
)
}
}
}
function resolveAsyncComponent ( factory: Function, baseCtor: Class<Component> ): Class<Component> | void {
if (isDef(factory.resolved)) {
// 3.在次渲染时可以拿到获取的最新组件
return factory.resolved
}
const resolve = once((res: Object | Class<Component>) => {
factory.resolved = ensureCtor(res, baseCtor)
if (!sync) {
forceRender(true) //2. 强制更新视图重新渲染
} else {
owners.length = 0
}
})
const reject = once(reason => {
if (isDef(factory.errorComp)) {
factory.error = true forceRender(true)
}
})
const res = factory(resolve, reject)// 1.将resolve方法和reject方法传入,用户调用 resolve方法后
sync = false
return factory.resolved
}
Vue.js的template编译
简而言之,就是先转化成AST树,再得到的render函数返回VNode(Vue的虚拟DOM节点),详细步骤如下:
首先,通过compile编译器把template编译成AST语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compile是createCompiler的返回值,createCompiler是用以创建编译器的。另外compile还负责合并option。
然后,AST会经过generate(将AST语法树转化成render funtion字符串的过程)得到render函数,render的返回值是VNode,VNode是Vue的虚拟DOM节点,里面有(标签名、子节点、文本等等)
nextTick在哪里使用?原理是?
nextTick中的回调是在下次DOM更新循环结束之后执行延迟回调,用于获得更新后的DOM- 在修改数据之后立即使用这个方法,获取更新后的
DOM - 主要思路就是采用
微任务优先的方式调用异步方法去执行nextTick包装的方法
nextTick方法主要是使用了宏任务和微任务,定义了一个异步方法.多次调用nextTick会将方法存入队列中,通过这个异步方法清空当前队列。所以这个nextTick方法就是异步方法
根据执行环境分别尝试采用
- 先采用
Promise Promise不支持,再采用MutationObserverMutationObserver不支持,再采用setImmediate- 如果以上都不行则采用
setTimeout - 最后执行
flushCallbacks,把callbacks里面的数据依次执行

回答范例
-
nextTick中的回调是在下次DOM更新循环结束之后执行延迟回调,用于获得更新后的DOM -
Vue有个异步更新策略,意思是如果数据变化,Vue不会立刻更新DOM,而是开启一个队列,把组件更新函数保存在队列中,在同一事件循环中发生的所有数据变更会异步的批量更新。这一策略导致我们对数据的修改不会立刻体现在DOM上,此时如果想要获取更新后的DOM状态,就需要使用nextTick -
开发时,有两个场景我们会用到
nextTick
-
created中想要获取DOM时 -
响应式数据变化后获取
DOM更新后的状态,比如希望获取列表更新后的高度
nextTick签名如下:function nextTick(callback?: () => void): Promise<void>
所以我们只需要在传入的回调函数中访问最新DOM状态即可,或者我们可以await nextTick()方法返回的Promise之后做这件事
- 在
Vue内部,nextTick之所以能够让我们看到DOM更新后的结果,是因为我们传入的callback会被添加到队列刷新函数(flushSchedulerQueue)的后面,这样等队列内部的更新函数都执行完毕,所有DOM操作也就结束了,callback自然能够获取到最新的DOM值

本文深入探讨Vue.js的关键面试问题,包括异步组件、模板编译、响应式原理、Vue3.0的变化、生命周期方法、路由模式、虚拟DOM优缺点以及与React的对比。讲解了Vue如何检测数组变化、如何实现虚拟DOM以及Vue采用异步渲染的原因。还讨论了Vue的diff算法、初始化页面闪动问题的解决方案和子组件与父组件的执行顺序。
最低0.47元/天 解锁文章
840

被折叠的 条评论
为什么被折叠?



