React---对虚拟DOM初识

一.首先我们要先了解以下两个概念

1.JSX

它是JavaScript的语法扩展,底层还是JavaScript,JavaScript有的功能它全有。

JSX生产的是React对象,可以将表达式放在花括号里,然后嵌入到JSX中,也就是说JSX能认识HTML标签,在编译之后(babel编译器)就会编程常规的JavaScript对象,也就是本文要说的虚拟DOM转换成真实DOM。

既然说是写在花括号里,那么if语句和for循环里都能写JSX语句,render() 方法就是React的核心,将虚拟DOM转化为真实DOM

import React, { Component } from 'react';
import ReactDom from 'react-dom';
class App extends Component {
  render() {
    return (
      <div className="App">
          <h2 id="vDom" style={{ color: "#f40" }}>虚拟DOM</h2>
          <div dangerouslySetInnerHTML={{ __html: content }}></div>
      </div>
    )
  }
}
export default App;
2.react-diff算法

大致就是传两个参数,一个是真实的DOM一个是虚拟DOM,比较两者的元素的类型、属性等,发现有不一样就砍了重新加上新的,使得两边一样。

二.虚拟DOM

1.概念

相当于就是JavaScript语句和页面上的DOM元素之间加了一个缓存,将真实的DOM转化为json对象,利用diff算法避免了没必要的操作,从而提高了效率,换句话就是真实的DOM我们获取它时,我们会把我们不需要用到的DOM元素属性都统统获取到,效率很低,利用虚拟DOM就可以避免

2.原理

一个diff函数有两个参数一个真实DOM一个虚拟DOM,使用递归对组件的文本节点、非文本的DOM节点、属性作比较,如果相同则不更新,如果不同则更新。

对比子节点时,子节点时一个数组,他们可能改变顺序(排序)或者数量发生变化(增删),我们很难确定要和虚拟DOM哪一个做比较,所以我们要给它们设置key,如果有key使用key查找子节点(高性能),如果没key按照DOM类型查找(低性能),

3.虚拟DOM的实现

我们一步一步看:
(1)首先我们需要引入babel(v6版本)
>网页也可以引入,点击这里去复制黏贴一下<

<script src="./js/babel.min.js"></script>

(2)我们在HTML里写我们的JS代码,插入script标签,type是text/babel

 <script src="./js/babel.min.js"></script>
    <script type="text/babel">
        
    </script>

代码就写在这里面

(3)我们就可以写JSX语句了

let vDOM = (<div id="app" name="app">
    hello world!
    <ul className= "ul">
        <li>虚拟DOM</li>
    </ul>
    <div>
        <p style={{color: "#f40"}}>学习虚拟DOM</p>
    </div>
</div>);

我们在末尾console.log(vDOM);查看一下
在这里插入图片描述
会报错,说React找不到,当然找不到,我们是自己写的东西,又没有引入任何React的东西,所以需要重写方法。

(4)重写createElement

 /*@jsx createElement*/

注:写在标签的顶部,@jsx是babel的自执行指令

/*@jsx createElement*/
let vDOM = (<div id="app" name="app">
    hello world!
    <ul className="ul">
        <li>虚拟DOM</li>
    </ul>
    <div>
        <p style={{ color: "#f40" }}>学习虚拟DOM</p>
    </div>
</div>);
function createElement(nodeName, attr, ...args) {
    return {
        nodeName: nodeName,
        attr: attr,
        children: [].concat(...args)
    }
}
console.log(vDOM);

再次控制台打印,就变成了json格式的虚拟DOM,包括nodeName、attr、children
在这里插入图片描述
(5)将虚拟DOM转化为真实DOM在页面中显示,就是自己写一render()方法

需要考虑是否是文本节点

function render(vnode) {
    //vnode是纯文本,创建文本节点
    if (vnode.split) {
        return document.createTextNode(vnode);
    }
    //不是文本
    let node = document.createElement(vnode.nodeName); //节点
    let attr = vnode.attr || []; // 属性
    Object.keys(attr).forEach((k) => {
        node.setAttribute(k, attr[k]);
    });
    (vnode.children || []).forEach((n) => {
        node.appendChild(render(n));//递归
    });
    return node;
}
let dom = render(vDOM);//将虚拟dom转化成真实dom的方法render()
document.body.appendChild(dom);

最后我们就可以在页面上看到显示
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值