虚拟 DOM 和 DOM diff

2020-12-24  本文已影响0人  张德瘦嬢嬢

概念

需要额外的创建函数,如 React 中的 createElement 或者 Vue 中的 h可以通过 JSX 来简化成 XML 写法 ,但 是需要额外的构建过程,严重依赖打包工具

关于DOM的谣言:DOM操作慢,虚拟操作DOM快?

为什么有谣言呢?

虚拟DOM长什么样子

  1. 在React中的虚拟DOM
const vNode = {
  key: null,
  props: {
    children: [
      {type: 'span', ...},
      {type: 'span', ...}
    ],
    className: "red",
    onClick: ()=>{}
  },
  ref: null,
  type: "div",
  ...
}
  1. 在Vue中的虚拟DOM
const vNode = {
  tag: 'div',
  data: {
    class: 'red',
    on: {
      click: ()=>{}
    }
  },
  children: [
    {tag: "span", ...},
    {tag: "span", ...}
  ],

创建虚拟DOM

  1. React
  createElement('div',{className:'red',onClick:()=> {}},[
    createElement('span', {}, 'span1'),
    createElement('span', {}, 'span2')
  ]
)
// 通过 JSX 简化
<div className="X" onClick="{()=> {}}">
    <span>span1</span>
    <span>span2</span>
</div>
//  通过 babel 转为 createElement 形式
  1. Vue
//  只能在 render 函数里得到 h
h('div', {
  class: 'red',
  on: {
    click: () => { }
  },
}, [h('span',{},'span1'), h('span', {}, 'span2'])
   
   
 // 通过简化JSX
<div class="red" @click="fn">
  <span>span1</span>
  <span>span2</span>
</div>
// 通过 vue-loader 转为 h 形式

DOM diff

  1. 把虚拟DOM想象成树形
    举例一:
<div :class="x">
    <span v-if="y">{string1}</span>
    <span>{string2}</span>
</div>
image

当数据变化,x从red变为green

image

此时DOM diff发现:

  1. 能减少不必要的DOM操作
    2.能跨平台渲染
    DOM diff缺点:
  2. 需要额外的创建函数,如createElement或h,但是可以通过JXS来简化成XML写法。
  3. 同级节点对比存在bug🔜解决方法:用Key值进行区分

举个栗子

如不加key的三个同级input标签,分别输入不同value:1、2、3,然后点击删除第二个,会发现留下的两个input中,value值是1、2而不是1、3。

image

点击删除2,你以为2被删除了,结果却是:

image

因为中间的删除第三个取代第二个的位置这个是我们人类认为的逻辑,计算机认为的逻辑是:第二个的改变,第三个的删除(神奇的算法逻辑)。

如何解决?

上一篇下一篇

猜你喜欢

热点阅读