• 虚拟 DOM 到底是什么?


    虚拟 DOM 到底是什么?

    是什么?

    虚拟 DOM (Virtual DOM )这个概念相信大家都不陌生,从 React 到 Vue ,虚拟 DOM 为这两个框架都带来了跨平台的能力(React-Native 和 Weex)。因为很多人是在学习 React 的过程中接触到的虚拟 DOM ,所以为先入为主,认为虚拟 DOM 和 JSX 密不可分。其实不然,虚拟 DOM 和 JSX 固然契合,但 JSX 只是虚拟 DOM 的充分不必要条件,Vue 即使使用模版,也能把虚拟 DOM 玩得风生水起,同时也有很多人通过 babel 在 Vue 中使用 JSX。

    很多人认为虚拟 DOM 最大的优势是 diff 算法,减少 JavaScript 操作真实 DOM 的带来的性能消耗。虽然这一个虚拟 DOM 带来的一个优势,但并不是全部。虚拟 DOM 最大的优势在于抽象了原本的渲染过程,实现了跨平台的能力,而不仅仅局限于浏览器的 DOM,可以是安卓和 IOS 的原生组件,可以是近期很火热的小程序,也可以是各种GUI。

    回到最开始的问题,虚拟 DOM 到底是什么,说简单点,就是一个普通的 JavaScript 对象,包含了 tagpropschildren 三个属性。

    <div id="app">
      <p class="text">hello world!!!</p>
    </div>

    上面的 HTML 转换为虚拟 DOM 如下:

    {
      tag: 'div',
      props: {
        id: 'app'
      },
      chidren: [
        {
          tag: 'p',
          props: {
            className: 'text'
          },
          chidren: [
            'hello world!!!'
          ]
        }
      ]
    }
    

    该对象就是我们常说的虚拟 DOM 了,因为 DOM 是树形结构,所以使用 JavaScript 对象就能很简单的表示。而原生 DOM 因为浏览器厂商需要实现众多的规范(各种 HTML5 属性、DOM事件),即使创建一个空的 div 也要付出昂贵的代价。虚拟 DOM 提升性能的点在于 DOM 发生变化的时候,通过 diff 算法比对 JavaScript 原生对象,计算出需要变更的 DOM,然后只对变化的 DOM 进行操作,而不是更新整个视图。

    那么我们到底该如何将一段 HTML 转换为虚拟 DOM 呢?

     

    从 h 函数说起

    观察主流的虚拟 DOM 库(snabbdomvirtual-dom),通常都有一个 h 函数,也就是 React 中的 React.createElement,以及 Vue 中的 render 方法中的 createElement,另外 React 是通过 babel 将 jsx 转换为 h 函数渲染的形式,而 Vue 是使用 vue-loader 将模版转为 h 函数渲染的形式(也可以通过 babel-plugin-transform-vue-jsx 插件在 vue 中使用 jsx,本质还是转换为 h 函数渲染形式)。

    我们先使用 babel,将一段 jsx 代码,转换为一段 js 代码:

    安装 babel 依赖

    npm i -D @babel/cli @babel/core @babel/plugin-transform-react-jsx

    配置 .babelrc

    {
        "plugins": [
            [
                "@babel/plugin-transform-react-jsx",
                {
                    "pragma": "h", // default pragma is React.createElement
                }
            ]
        ]
    }

    转译 jsx

    在目录下新建一个 main.jsx

    function getVDOM() {
      return (
        <div id="app">
          <p className="text">hello world!!!</p>
        </div>
      )
    }
    

    使用如下命令进行转译:

    npx babel main.jsx --out-file main-compiled.js

     

  • 相关阅读:
    model number
    LeetCode: Largest Rectangle in Histogram 解题报告
    Leetcode:Edit Distance 解题报告
    Leetcode:Interleaving String 解题报告
    Leetcode:Scramble String 解题报告
    Leetcode:【DP】Longest Palindromic Substring 解题报告
    Leetcode:Longest Substring Without Repeating Characters 解题报告
    Leetcode: Remove Duplicates from Sorted List II 解题报告
    Leetcode:Flatten Binary Tree to Linked List 解题报告
    LeetCode: Convert Sorted Array to Binary Search Tree 解题报告
  • 原文地址:https://www.cnblogs.com/chucklu/p/15731616.html
Copyright © 2020-2023  润新知