Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

《8分钟学会 Vue.js 原理》四、虚拟节点 vnode 生成真实DOM #10

Open
JuniorTour opened this issue Apr 10, 2022 · 0 comments

Comments

@JuniorTour
Copy link
Owner

JuniorTour commented Apr 10, 2022

DEMO:https://jsbin.com/lekajaw/edit?html,output

TODO 正在热火朝天更新中,欢迎催更~

核心原理

虚拟节点vnode:

vnode = {
  "tag": "div",
  "children": [
    {
      "text": "hi, Vue.js"
    }
  ],
}

渲染出真实DOM HTML:

  <div>hi, Vue.js</div>
  1. 调用vm.patch(vm.$el, vnode)方法,传入旧节点和新节点作为参数。第一次渲染的旧节点是一个空的虚拟节点:emptyNodeAt(elm)
  2. 对新旧节点进行diff比较:DEMO 中为了简化逻辑,没有涉及,TODO: 专题研究。
  3. 调用nodeOps.createElement(tag, vnode),基于tag等属性,将虚拟节点转化为真实DOM,赋值给vnode.elm
  4. children属性中的子元素,进行遍历,对每个子元素调用this.createElm()递归生成真实DOM,底层基于document.createTextNode(text)等原生DOM API实现。
  5. 调用insert(parentElm, vnode.elm, refElm);,将生成的子元素真实DOM树,插入到父元素中;将新节点完整的真实DOM树,插入到body元素中。底层基于parentNode.insertBefore, node.appendChild(child)等原生DOM API实现。
  6. 最后,调用this.removeVnodes(oldVnode),删除旧节点对应的真实DOM,基于原生DOM API:node.removeChild(child);实现。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant