virtual dom 虚拟DOM
2020-02-13 21:46
71 查看
- vdom是vue和React的核心,先讲哪个都绕不开它
- vdom比较独立,使用也比较简单
- 如果面试闻到vue和React和实现,免不了问vdom
vdom是什么?为何会存在vdom?
- virtual dom,虚拟DOM
- 用JS模拟DOM结构
- 将DOM对比操作放在JS层来做,提高效率
- 提高重绘性能
为何会存在:
- DOM操作是“昂贵”的,js运行效率高
- 尽量减少DOM操作,而不是“推倒重来”
- 项目越复杂,影响就越严重
- vdom即可解决这个问题
vdom如何应用,核心API是什么
使用snabbdom
<body> <div id="container"></div> <button id="btn-change">change</button> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-class.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-props.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-style.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-eventlisteners.js"></script> <script src="https://cdn.bootcss.com/snabbdom/0.7.1/h.js"></script> <script> var snabbdom = window.snabbdom // 定义patch var patch = snabbdom.init([ snabbdom_class, snabbdom_props, snabbdom_style, snabbdom_eventlisteners ]) // 定义h var h = snabbdom.h var container = document.getElementById('container') // 生成vnode var vnode = h('ul#list', {}, [ h('li.item', {}, 'Item 1'), h('li.item', {}, 'Item 2') ]) patch(container, vnode) document.getElementById('btn-change').addEventListener('click', function(){ var newVnode = h('ul#list', {}, [ h('li.item', {}, 'Item 1'), h('li.item', {}, 'Item B'), h('li.item', {}, 'Item 3') ]) patch(vnode, newVnode) }) </script> </body>
介绍一下diff算法
- 什么是diff算法?
- vdom为何用diff算法?
(1)DOM操作是“昂贵”的,因此尽量减少DOM操作
(2)找出本次DOM必须更新的节点来更新,其他的不更新
(3)这个“找出”的过程,就需要diff算法 - diff算法实现流程
(1)patch(container, vnode)
(2)patch(vnode, newVnode)
// patch(container, vnode)情况 function createElement(vnode){ var tag = vnode.tag var attrs = vnode.attrs || {} var children = vnode.children || [] if(!tag){ return null } // 创建元素 var elem = document.createElement(tag) // 属性 var attrName for(attrName in attrs){ if(attrs.hasOwnProperty(attrName)){ // 给elem添加属性 elem.setAttribute(attrName, attrs[attrName]) } } children.forEach(childVnode => { // 给elem田间子元素 elem.appendChild(createElement(childVnode)) // 递归 }) // 返回真实的DOM元素 return elem } // 数据 { tag: 'ul' attrs: {id: 'list'}, children: [ { tag: 'li', attrs: {className: 'item'}, children: ['Item 1'] }, { tag: 'li', attrs: {className: 'item'}, children: ['Item 2'] } ] }
// patch(vnode, newVnode)情况 function updateChildren(vnode, newVnode){ var children = vnode.children || [] var newChildren = newVnode.children || [] // 遍历现有的children children.forEach(function(child, index){ var newChild = newXChildren[index] if(newChild == null){ return } if(child.tag === newChild.tag){ // 两者tag一样 updateChildren(child, newChild) } else { replaceNode(child, newChild) } }) }
核心API:
- h函数
- patch函数
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- Virtual DOM 虚拟DOM的理解(转)
- virtualenvwrapper虚拟环境与django的安装
- vue底层原理之虚拟DOM(VDOM)和diff算法
- CentOS7-VSFTPD-虚拟用户(virtual-user)-设置
- 用windbg实现虚拟地址到物理地址转换(Converting Virtual Addresses to Physical Addresses)
- Postfix有关Virtual、Aliases、虚拟表等概念之间的关系
- VirtualBox+CentOs虚拟集群搭建配置hadoop2.2.0学习环境
- 深入Vue2.x的虚拟DOM diff原理
- Nginx虚拟主机配置实例(Nginx VirtualHost Example)
- VUE、React中虚拟DOM(virtual DOM)技术 VNode及diff算法介绍
- 解决:配置虚拟主机,重启apache,[warn] _default_ VirtualHost overlap on port 80, the first has precedence
- 深刻理解 React (一) ——JSX和虚拟DOM
- Vue使用虚拟dom进行渲染view的方法
- 使用virtualenvwrapper安装配置python虚拟环境
- 搭建python虚拟环境和 virtualenvwrapper-win 使用(windows系统下)
- Apache配置基于IP的虚拟主机 Apache virtual host configuration is based on the IP
- unity虚拟摇杆控制 Virtual Joystick
- 解决Ubuntu16.04或14.04安裝创建虚拟环境时virtualenvwrapper不存在的问题
- Ubuntu安装虚拟环境中出现/usr/bin/python: No module named virtualenvwrapper virtualenvwrapper.sh: ...
- 深刻理解React(-) --JSX和虚拟DOM