vue对比react挂载dom流程
vue:template标签解析时,
1.将模板字符串通过parse函数转换成为AST(抽象语法树)
2.将AST通过generate函数转换成为render函数
3.在这个render函数中又有很多h函数(createElement函数),调用这些h函数生成一个又一个对象,这些对象互相存在联系从而生成虚拟dom树
export const createCompiler = createCompilerCreator(function baseCompile (
template: string,
options: CompilerOptions
): CompiledResult {
// 1.parse,模板字符串 转换成 抽象语法树(AST)
const ast = parse(template.trim(), options)
// 2.optimize,对 AST 进行静态节点标记
if (options.optimize !== false) {
optimize(ast, options)
}
// 3.generate,抽象语法树(AST) 生成 render函数代码字符串
const code = generate(ast, options)
return {
ast,
render: code.render,
staticRenderFns: code.staticRenderFns
}
})
虚拟dom和ast的区别
虚拟dom和ast即抽象语法树,都涉及到了页面渲染,刚开始学习的时候我经常将两者混淆,其实两者是截然不同的概念。两者都是使用对象来进行抽象表示,但是虚拟dom是将真实dom以对象的方式进行抽象表示,而ast则是对语法结构的抽象表示。
虚拟Vnode怎么映射成真实DOM?
调用Vue原型上_update方法,将虚拟DOM映射成为真实的DOM。从源码上可以知道,_update的调用时机有两个,一个是发生在初次渲染阶段,另一个发生数据更新阶段
备注:在虚拟dom中,都由elm属性,就是真实dom,也就是说,生成的虚拟dom同时,都创出了真实dom,也就是说,第一次的渲染,vue比单纯创建dom元素要效率低,vue的高效体现在响应式数据变化的虚拟dom对比
vm._update
lifecycleMixin()
function lifecycleMixin() {
Vue.prototype._update = function (vnode, hydrating) {
var vm = this;
var prevEl = vm.$el;
var prevVnode = vm._vnode; // prevVnode为旧vnode节点
// 通过是否有旧节点判断是初次渲染还是数据更新
if (!prevVnode) {
// 初次渲染
vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false)
} else {
// 数据更新
vm.$el = vm.__patch__(prevVnode, vnode);
}
}
在update中调用patch生成真实dom
patch函数核心是通过调用createElment方法进行dom操作,创建节点,插入子节点,递归创建一个完整的DOM树并插入到body中。并且在产生真实阶段阶段,会有diff算法来判断前后Vnode的差异,以求最小化改变真实阶段
react:
◼ 实际上,jsx 仅仅只是 React.createElement(component, props, …children) 函数的语法糖。
所有的jsx最终都会被转换成React.createElement的函数调用。
createElement需要传递三个参数:
◼ 参数一:type
当前ReactElement的类型;
如果是标签元素,那么就使用字符串表示 “div”;
如果是组件元素,那么就直接使用组件的名称;
◼ 参数二:config
所有jsx中的属性都在config中以对象的属性和值的形式存储;
比如传入className作为元素的class;
◼ 参数三:children
存放在标签中的内容,以children数组的方式进行存储;
当然,如果是多个元素呢?React内部有对它们进行处理,处理的源码在下方
这个ReactElement对象是什么作用呢?React为什么要创建它呢?
原因是React利用ReactElement对象组成了一个JavaScript的对象树;
JavaScript的对象树就是虚拟DOM(Virtual DOM);
虚拟dom的作用?
1.在页面发生更新时,虚拟dom通过diff算法来进行对比,然后将变化重新渲染到界面上,而不是渲染整个页面,提高了程序的性能
2.虚拟DOM最大的好处在于抽象了渲染的过程,为应用带来了跨平台的能力,不再是仅仅局限于浏览器端。比如React-Native和WeeX可以运行在Android、IOS平台上。同样的虚拟dom,在web端渲染成一个button,在手机端渲染成一个button控件…