React学习第四天—Virtual DOM 及 Diff 算法(三)

这是我参与更文挑战的第8天

前面我们已经将virtualDOM转化为真实DOM了,但是这些真实DOM是没有任何属性的,接下来我们就为真实DOM添加属性

为真实DOM添加属性

分析:
这些属性全部存储在虚拟DOM的props里面,我们只需要在创建元素的时候找到virtualDOM的属性props,然后遍历props属性,在遍历的过程当中就可以将这些属性添加给真实DOM元素了,但是在添加属性的时候我们还需要考虑一些不同的情况,因为不同情况我们要去做不同的处理,如果是事件属性,那么我们就要为该元素去添加事件;还要判断这个属性是否是value属性或者是checked属性,因为这两个属性是无法使用setAttribute方法去设置它的,我们还需要看看这个属性是否是children属性,children不是属性是子元素但是也存在props中;还需要看这个属性是否是className属性,如果是className的话我们就给元素添加class属性;如果是普通属性就可以用setAttribute方法给真实DOM去设置就行了。

代码实现:

export default function updateNodeElement(newElement, virtualDOM) {
  // 获取节点对应的属性对象
  const newProps = virtualDOM.props

  Object.keys(newProps).forEach(propName => {
    // 获取属性值
    const newPropsValue = newProps[propName]

    // 判断属性是否是事件属性 onClick => click

    if(propName.slice(0, 2) === "on") {
      const eventName = propName.toLowerCase().slice(2)
      // 为元素添加事件
      newElement.addEventListener(eventName, newPropsValue)
    } else if(propName === "value" || propName === "checked") {
      newElement[propName] = newPropsValue
    } else if (propName !== "children") {
      if(propName === "className") {
        newElement.setAttribute('class', newPropsValue)
      } else {
        newElement.setAttribute(propName, newPropsValue)
      }
    }
  })
}

复制代码

在生成真实DOM文件夹引用这个方法:

import updateNodeElement from "./updateNodeElement"

export default function mountNativeElement (virtualDOM, container)  {
  let newElement = null
  ···
  else {
    // 元素节点
    newElement = document.createElement(virtualDOM.type);
    updateNodeElement(newElement, virtualDOM);

复制代码

小结:
当我们创建真实元素节点的时候,调用updateNodeElement给这个元素添加属性,属性存在virtualDOM的props中,所以这个updateNodeElement传两个参数,一个是当前的真实DOM,newElement(给谁设置属性),一个是virtualDOM(这些属性藏在哪),在把props里面的属性全部拿出来,属性为事件使用addEventListener添加监听事件,value和checked使用newElement[propName] = newPropsValue,接下来除children这个节点,其他节点为className转化为class,其他的直接setAttribute。

组件渲染之区分函数组件和类组件

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享