Vue2源码梳理:vdom结构与createElement的实现

createElement的用法 document.createElement()是在对象中创建一个对象,要与appendChild() 或 insertBefore()方法联合使用。其中,appendChild() 方法在节点的子节点列表末添加新的子节点。insertBefore() 方法在节点的子节点列表任意位置插入新的节点。 阅读详情

vdom 结构

  • 浏览器原生dom对象,本身就是一个非常复杂的对象,单单把 div 这个dom对象拿出来,遍历它的属性,将是一个庞大的存在
  • 因为浏览器的标准就是把这个dom设计的非常复杂,所以当我们去频繁的操作dom的话,一定会有一些性能问题
  • vdom(Virtual DOM), 其实就是用一个原生的js对象去描述一个dom节点,它的创建比创建一个真实的dom的代价要小很多
  • 在vue.js中的 vdom 的定义在 src/core/vdom/vnode.js
    /* @flow */
    export default class VNode {
      tag: string | void;
      data: VNodeData | void;
      children: ?Array<VNode>; // 树形结构
      text: string | void;
      elm: Node | void;
      ns: string | void;
      context: Component | void; // rendered in this component's scope
      key: string | number | void;
      componentOptions: VNodeComponentOptions | void;
      componentInstance: Component | void; // component instance
      parent: VNode | void; // component placeholder node
    
      // strictly internal
      raw: boolean; // contains raw HTML? (server only)
      isStatic: boolean; // hoisted static node
      isRootInsert: boolean; // necessary for enter transition check
      isComment: boolean; // empty comment placeholder?
      isCloned: boolean; // is a cloned node?
      isOnce: boolean; // is a v-once node?
      asyncFactory: Function | void; // async component factory function
      asyncMeta: Object | void;
      isAsyncPlaceholder: boolean;
      ssrContext: Object | void;
      fnContext: Component | void; // real context vm for functional nodes
      fnOptions: ?ComponentOptions; // for SSR caching
      devtoolsMeta: ?Object; // used to store functional render context for devtools
      fnScopeId: ?string; // functional scope id support
    
      constructor (
        tag?: string,
        data?: VNodeData,
        children?: ?Array<VNode>,
        text?: string,
        elm?: Node,
        context?: Component,
        componentOptions?: VNodeComponentOptions,
        asyncFactory?: Function
      ) {
        this.tag = tag
        this.data = data
        this.children = children
        this.text = text
        this.elm = elm
        this.ns = undefined
        this.context = context
        this.fnContext = undefined
        this.fnOptions = undefined
        this.fnScopeId = undefined
        this.key = data && data.key
        this.componentOptions = componentOptions
        this.componentInstance = undefined
        this.parent = undefined
        this.raw = false
        this.isStatic = false
        this.isRootInsert = true
        this.isComment = false
        this.isCloned = false
        this.isOnce = false
        this.asyncFactory = asyncFactory
        this.asyncMeta = undefined
        this.isAsyncPlaceholder = false
      }
    
      // DEPRECATED: alias for componentInstance for backwards compat.
      /* istanbul ignore next */
      get child (): Component | void {
        return this.componentInstance
      }
    }
    
  • 上述 VNodeData,定义在 flow/vnode.js 中
    declare interface VNodeData {
      key?: string | number;
      slot?: string;
      ref?: string;
      is?: string;
      pre?: boolean;
      tag?: string;
      staticClass?: string;
      class?: any;
      staticStyle?: { [key: string]: any };
      style?: string | Array<Object> | Object;
      normalizedStyle?: Object;
      props?: { [key: string]: any };
      attrs?: { [key: string]: string };
      domProps?: { [key: string]: any };
      hook?: { [key: string]: Function };
      on?: ?{ [key: string]: Function | Array<Function> };
      nativeOn?: { [key: string]: Function | Array<Function> };
      transition?: Object;
      show?: boolean; // marker for v-show
      inlineTemplate?: {
        render: Function;
        staticRenderFns: Array<Function>;
      };
      directives?: Array<VNodeDirective>;
      keepAlive?: boolean;
      scopedSlots?: { [key: string]: Function };
      model?: {
        value: any;
        callback: Function;
      };
    };
    
  • vdom实际上它比真实的dom对象创建的代价要小很多
  • vdom 是借鉴了一个开源库 snabbdom 的实现
  • 它的设计比较巧,实现的diff算法和react是不太一样的,号称是性能非常高的
  • 除了vuejs,其他的vdom的实现也是基于它的
  • 所以,它是 vue.js 实现的一个基础, 但在它上面又做了很多扩展
  • 总结来说
    • vNode 它其实就是对原生dom的一种抽象的描述
    • 它的核心无非就几个关键属性,如:标签名、数据、子节点、键值等
    • 那其他属性它其实都是来为来扩展 vnode 灵活性以及实现一些特殊feature
    • 由于 vNode 它只是用来映射真实dom渲染的,它不需要包括这些操作dom的方法
    • 所以说它是比较轻量和简单的
    • vdom 除了它的数据结构的定义映射到真实的dom
    • 还有create, diff 和 patch 的过程
    • 在 vNode 的 create 的过程就是通过 createElement 方法
    • 也就是在 render 函数中调用的vm.$createElement 返回的Vnode

createElement 的实现

  • 在 render 函数提到的生成vnode方法,也就是它最终会调用这个 createElement 的方法来生成vnode
  • render方法,它最终就会调用 option.render 函数
  • 这个函数的执行分为两种情况
    • 一种情况就是通过把模板编译出来的 render 函数,它内部实际上会调用 vm._c
    • 而用户手写的render函数,最终会调用 vm.$createElement 这这个方法
    • 这两个方法最终都会调用这个 createElement 这个函数
    • 它的函数唯一的区别就是最后一个参数,也就是这六个参数,false 或 true
      // initRender 函数中
      vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
      vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)
      
  • 进入 createElement,定义在 src/core/vdom/create-element.js 中
    const SIMPLE_NORMALIZE = 1
    const ALWAYS_NORMALIZE = 2
    
    export function createElement (
      context: Component,
      tag: any,
      data: any,
      children: any,
      normalizationType: any,
      alwaysNormalize: boolean
    ): VNode | Array<VNode> {
      // 这个是参数检测,如果符合,说明,第三个参数是 children, 后面的参数前移
      // 这时候,之前的 data 变成了 children, 之前的 children 变成了 normalizationType
      // 对 children 做一个data的赋值,并且清理 data
      if (Array.isArray(data) || isPrimitive(data)) {
        normalizationType = children
        children = data
        data = undefined
      }
      // 基于最后一个参数,改变倒数第二个参数
      if (isTrue(alwaysNormalize)) {
        normalizationType = ALWAYS_NORMALIZE
      }
      return _createElement(context, tag, data, children, normalizationType)
    }
    
    • 它定义支持了六个参数
      • 第一个参数 是 vm 实例
      • 第二个就是 vnode的tag标签
      • 第三个就是data,就是跟vNode相关的一些数据
      • 第四个children是它的一些子节点 vnode, 由此构造出vNode tree, 完美映射 dom tree
    • 内部对参数个数不一致,进行处理
    • 最终调用 _createElement
    • 也就是这个函数,主要是用于处理参数的
    • 进入 _createElement
      export function _createElement (
        context: Component,
        tag?: string | Class<Component> | Function | Object,
        data?: VNodeData,
        children?: any,
        normalizationType?: number
      ): VNode | Array<VNode> {
        // 响应式对象会被添加上 __ob__ 这个属性
        // 首先对 data 做校验,data是不能是响应式的,否则进行警告
        if (isDef(data) && isDef((data: any).__ob__)) {
          process.env.NODE_ENV !== 'production' && warn(
            `Avoid using observed data object as vnode data: ${JSON.stringify(data)}\n` +
            'Always create fresh vnode data objects in each render!',
            context
          )
          // 创建一个 空的VNode, 这个 VNode 本质上就是一个 注释 VNode
          return createEmptyVNode()
        }
        // 获取 component is
        // object syntax in v-bind
        if (isDef(data) && isDef(data.is)) {
          tag = data.is
        }
        if (!tag) {
          // in case of component :is set to falsy value
          return createEmptyVNode()
        }
        // warn against non-primitive key
        if (process.env.NODE_ENV !== 'production' &&
          isDef(data) && isDef(data.key) && !isPrimitive(data.key)
        ) {
          if (!__WEEX__ || !('@binding' in data.key)) {
            warn(
              'Avoid using non-primitive value as key, ' +
              'use string/number value instead.',
              context
            )
          }
        }
        // 接着对插槽进行处理
        // support single function children as default scoped slot
        if (Array.isArray(children) &&
          typeof children[0] === 'function'
        ) {
          data = data || {}
          data.scopedSlots = { default: children[0] }
          children.length = 0
        }
        // 对 children 做 normalize, 当手写 render 函数时,比如传递一个字符串作为children
        // 但是 children 实际上是一个数组,每一个数组都是 vnode
        // 另外在编译的时候,会有不同的情况产生
        if (normalizationType === ALWAYS_NORMALIZE) {
          children = normalizeChildren(children)
        } else if (normalizationType === SIMPLE_NORMALIZE) {
          children = simpleNormalizeChildren(children)
        }
        // 对children进行 normalize 后就能很好处理children了
        let vnode, ns
        // 对 tag 做一些判断
        // tag 可能是 string 也可能是组件
        if (typeof tag === 'string') {
          let Ctor
          ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag)
          // 判断是否是html保留标签
          if (config.isReservedTag(tag)) {
            // platform built-in elements
            if (process.env.NODE_ENV !== 'production' && isDef(data) && isDef(data.nativeOn) && data.tag !== 'component') {
              warn(
                `The .native modifier for v-on is only valid on components but it was used on <${tag}>.`,
                context
              )
            }
            // 创建一些平台内建元素实例化的vnode
            vnode = new VNode(
              config.parsePlatformTagName(tag), data, children,
              undefined, undefined, context
            )
          // 对组件的解析
          } else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
            // component
            vnode = createComponent(Ctor, data, context, children, tag)
          } else {
            // unknown or unlisted namespaced elements
            // check at runtime because it may get assigned a namespace when its
            // parent normalizes children
            // 不认识的标签,则直接创建
            vnode = new VNode(
              tag, data, children,
              undefined, undefined, context
            )
          }
        } else {
          // direct component options / constructor
          vnode = createComponent(tag, data, context, children)
        }
        if (Array.isArray(vnode)) {
          return vnode
        } else if (isDef(vnode)) {
          if (isDef(ns)) applyNS(vnode, ns)
          if (isDef(data)) registerDeepBindings(data)
          return vnode
        } else {
          return createEmptyVNode()
        }
      }
      
    • _createElement 才是真正创建 vNode 的参数
    • 进入 simpleNormalizeChildren,定义在 src/core/vdom/helpers/normalize-children.js
      /* @flow */
      
      import VNode, { createTextVNode } from 'core/vdom/vnode'
      import { isFalse, isTrue, isDef, isUndef, isPrimitive } from 'shared/util'
      
      // The template compiler attempts to minimize the need for normalization by
      // statically analyzing the template at compile time.
      //
      // For plain HTML markup, normalization can be completely skipped because the
      // generated render function is guaranteed to return Array<VNode>. There are
      // two cases where extra normalization is needed:
      
      // 1. When the children contains components - because a functional component
      // may return an Array instead of a single root. In this case, just a simple
      // normalization is needed - if any child is an Array, we flatten the whole
      // thing with Array.prototype.concat. It is guaranteed to be only 1-level deep
      // because functional components already normalize their own children.
      // 这个方法很简单,就是把当前一层给合并拍平,不考虑里面的深层,不考虑递归
      export function simpleNormalizeChildren (children: any) {
        for (let i = 0; i < children.length; i++) {
          if (Array.isArray(children[i])) {
            return Array.prototype.concat.apply([], children)
          }
        }
        return children
      }
      
      // 2. When the children contains constructs that always generated nested Arrays,
      // e.g. <template>, <slot>, v-for, or when the children is provided by user
      // with hand-written render functions / JSX. In such cases a full normalization
      // is needed to cater to all possible types of children values.
      // 基础类型,返回text基础类型;否则判断是数组,进行处理,否则是undefined
      export function normalizeChildren (children: any): ?Array<VNode> {
        return isPrimitive(children)
          ? [createTextVNode(children)]
          : Array.isArray(children)
            ? normalizeArrayChildren(children)
            : undefined
      }
      
      function isTextNode (node): boolean {
        return isDef(node) && isDef(node.text) && isFalse(node.isComment)
      }
      
      // 存储返回的 res 数组,遍历children, children 本身又是 array, 它处理有可能的多层嵌套,递归处理
      // 子节点,像 slot, v-for 可能生成 深层数据结构
      function normalizeArrayChildren (children: any, nestedIndex?: string): Array<VNode> {
        const res = [] // 最终返回的结果集
        let i, c, lastIndex, last
        // 遍历 children
        for (i = 0; i < children.length; i++) {
          c = children[i]
          if (isUndef(c) || typeof c === 'boolean') continue
          lastIndex = res.length - 1
          last = res[lastIndex]
          //  nested 对嵌套数据结构进行处理
          if (Array.isArray(c)) {
            if (c.length > 0) {
              // 这里进行递归调用,将结果存入c
              c = normalizeArrayChildren(c, `${nestedIndex || ''}_${i}`)
              // merge adjacent text nodes 合并文本节点
              // 下次处理的第一个节点和最后一个节点都是文本节点,考虑合并
              if (isTextNode(c[0]) && isTextNode(last)) {
                res[lastIndex] = createTextVNode(last.text + (c[0]: any).text)
                c.shift()
              }
              // 最终push c
              res.push.apply(res, c)
            }
          // 是否是基础类型
          } else if (isPrimitive(c)) {
            // 匹配文本节点
            if (isTextNode(last)) {
              // merge adjacent text nodes
              // this is necessary for SSR hydration because text nodes are
              // essentially merged when rendered to HTML strings
              res[lastIndex] = createTextVNode(last.text + c)
            } else if (c !== '') {
              // convert primitive to vnode
              res.push(createTextVNode(c))
            }
          } else {
            if (isTextNode(c) && isTextNode(last)) {
              // merge adjacent text nodes
              res[lastIndex] = createTextVNode(last.text + c.text)
            } else {
              // default key for nested array children (likely generated by v-for)
              if (isTrue(children._isVList) &&
                isDef(c.tag) &&
                isUndef(c.key) &&
                isDef(nestedIndex)) {
                c.key = `__vlist${nestedIndex}_${i}__`
              }
              res.push(c)
            }
          }
        }
        return res
      }
      
      • 其实 normalizeArrayChildren 比 simpleNormalizeChildren 做的更多的是
        • 递归处理很多层,拍平到一维数组中
        • 最后处理节点和新处理节点同样是文本节点,进行合并
        • 最终 normalizeArrayChildren 要把深层数据变成一维vnode数组
  • 以上是 createElement 创建 VNode 的过程
  • 每个 VNode 有 children,children 每个元素也是一个 VNode
  • 这样就形成了一个 VNode Tree,它很好的描述了我们的 DOM Tree
Vue 用createElement 自定义列表头 文章目录Vue 用createElement 自定义列表头一、前言二、需求实现效果三、知识点1、createElement 参数深入 data 对象2、createElement 创建元素过程四、具体实现及代码1、第一步:创建需要自定义列表头的table二、第二步:创建自定义组件封装el-popover三、局部注册组件并手写createElement五、扩展知识点1、Vue源码9个基础方法 Vue 用createElement 自定义列表头 一、前言 最近产品有需求,想要把一个搜索框放入到列表头中,一般的属 阅读详情

相关推荐

锐捷防火墙(WEB)——混合模式(VDOM)场景

虚拟域(VDOM),可以理解为虚拟防火墙,是一种将一个RG-WALL设备分为两个或两个以上虚拟设备的技术,它能起到多个独立设备的作用。VDOM可提供单独防火墙策略,在NAT/路由模式下,它可完全分开配置,从而为各连通网络或组织提供路由或VPN服务,同时VDOM之间也可以互访。设备的系统资源可以手动分配给不同的VDOM。一般常用于需要完成独立分割的多个网络,比如云环境;由于NGFW只能切换成nat和透明的其中一种模式,所以在既有透明又有nat路由的混合环境下必须使用VDOM模式来实施”

君逍遥o 1083

Vue2源码学习笔记 - 19.渲染与编译—createElement 函数

函数主要是在调用 render 函数时创建元素的vnode。对于各种类型的子节点在调用 normalizeChildren\simpleNormalizeChildren 规范化扁平化之后存于children属性中。对于HTML\SVG 类标签直接 new VNode 创建,组件则调用 createComponent 创建。最后返回 Vnode 对象或者数组,以供后续渲染操作。...

小问's blog 2989

从调节阀到步进电机:图解位置型PID与增量式PID的核心区别

本文深入解析了位置型PID与增量式PID的核心区别。通过调节阀和步进电机的实例,阐明位置式PID输出绝对位置,适用于直接控制执行机构;而增量式PID输出位置变化量,天然支持无扰动切换,更适合步进电机等场景。文章重点剖析了增量式PID在系统安全与平滑切换方面的关键优势。

weixin_29051811的博客 360

Vue 中 createElement 使用详解

test

陆小森_红齐飘飘的博客 4万+

阿里云Windows服务器部署网站全流程:从IIS配置到安全上线

Web服务器是承载网站应用、处理HTTP请求的核心软件。其工作原理是监听特定网络端口,接收客户端请求,并返回相应的网页、文件或动态生成的内容。在Windows Server环境中,IIS(Internet Information Services)作为微软官方Web服务器,凭借其与操作系统深度集成、图形化管理界面和对ASP.NET等微软技术栈的良好支持,成为许多开发者和运维人员的首选。其技术价值在于提供了稳定、可扩展的托管平台,支持从简单的静态网站到复杂的企业级Web应用。在云服务器普及的今天,将IIS部署

weixin_33552698的博客 327

FlowPic实战:从流量到图像的端到端加密应用识别

本文深入解析了FlowPic技术如何将网络流量转化为图像,并利用CNN模型进行端到端加密应用识别。该方法通过分析数据包大小和时序信息生成流量图像,有效绕过加密内容,实现对视频、聊天、文件传输等应用的精准分类。文章提供了从流量抓取、图像生成到轻量级CNN模型设计与训练的完整实战指南,并探讨了在VPN、Tor等复杂场景下的应用与挑战。

weixin_29046035的博客 151

Vue2源码梳理:render函数的实现

在 $mount 时,会调用 render 方法,在写 template 时,最终也会转换成 render 方法,Vue 的 _render 方法是实例的一个私有方法,它用来把实例渲染成一个虚拟 Node

Wang的专栏 1322

ARM学习 | 紧耦合存储器 (TCM)

TCM 是一种专用的片上存储器,直接与处理器核心耦合。确定性访问:由于不涉及缓存替换或一致性管理,访问延迟固定。高带宽:TCM 通常通过专用总线连接处理器核心,可以提供更高的数据吞吐率。用户管理:TCM 的分配和管理完全由开发者控制,不依赖硬件缓存策略。ARM 处理器中的 TCM 通常分为ITCM(指令紧耦合存储器)和DTCM(数据紧耦合存储器),分别用于存储指令和数据。TCM 是 ARM 处理器中不可忽视的重要特性,在实时系统和高性能嵌入式应用中具有重要地位。

qq_43167806的博客 3330

Vue2源码梳理:update的整体实现流程

回到之间 $mount时,mountComponent 函数的过程,vm._render 是如何创建了一个 VNode,接下来就是要把这个 VNode 渲染成一个真实的 DOM 并渲染出来,这个过程是通过 vm._update 完成的,_update 它是一个vue 的私有方法,它把我们的 vnode 渲染成真实的 dom,_update的方法,也是原型上的一个方法, 它的定义在src/core/instance/lifecycle.js 中

Wang的专栏 2308

OpenClaw人人养虾:接入Matrix

Matrix 是一个开放的去中心化通讯协议(Decentralized Communication Protocol),任何人都可以搭建自己的 Homeserver(家服务器)并与全球 Matrix 网络互联。OpenClaw 通过 Matrix Client-Server API 实现接入。

王国平的博客 528

SRS流媒体服务器在Windows下的安装

在之前的流媒体开发中(视频会议),我基本上使用nginx加模块的方式进行学习、测试,正式开发的时候改为服务器端用EasyDarwin,客户端用rtsp-simple-server(这些流媒体服务器的用法见我以前的博文),这样可以充分利用客户端的资源,降低服务器端的压力。在流媒体协议方案,我选择相对较快的rtsp。这个协议优点是支持UDP协议,优化好的环境下可以实现3秒以下的延迟,基本满足甲方要求,缺点就是不支持网页播放。

dgnankai的专栏 2023

vue 中render执行流程梳理

用了多年vue 今天对自己了解的render 做一个梳理 一、使用template模板 先从vue 初始化开始: 众所周知项目的main.js中定义了 var app = new Vue({})这vue初始化操作 其实他会执行到 这个方法中的_init函数,在这个方法执行一些列的初始化后,判断$options是否定义el,如果定义调用 vm.$mount(vm.$options.el)函数,...

奔跑的痕迹的博客 1837

Cilium动手实验室: 精通之旅---1.Getting Started with Cilium

我们需要在 HTTP 层的第 7 层实施策略,以限制允许 tiefighter 调用的确切 API,以及不允许调用哪些 API。上仅需要的 API 资源的访问,从而为微服务之间的通信实施“最低权限”安全方法。船只上进行匹配,因此我们需要在该标签上进行匹配,此外,我们必须确保来自带有标签。为了模拟我们的连接测试,我们将使用 curl 执行简单的 API 调用。在我们立即开始更改策略之前,让我们考虑一下相应的网络策略应该是什么样子。的规则,该规则将通过 L3-L4 策略对死星的访问限制为仅帝国船只。

Q先生 1128

Vue.js 源码分析:createComponent 如何把组件选项对象变成组件 VNode

`createComponent` 是 Vue.js 渲染管线中连接"组件选项对象"与"虚拟 DOM"的关键函数:当渲染函数执行到 `createElement` 时,普通 HTML 标签会直接生成元素 VNode,而组件(无论是模板中注册的标签、`h(Component)` 直传的组件对象,还是 `data.is` 动态绑定的组件)最终都会汇入 `createComponent`,产出一个携带构

gitblog_00080的博客 429

Unreal从入门到精通之如何绘制用于VR的3DUI交互的手柄射线

之前我写过一篇文章《Unreal5从入门到精通之如何在VR中使用3DUI》,其中讲到使用WidgetComponent和3DUI进行交互。然而,这种方法存在一个问题:为了让射线可视化,我们需要勾选“调试/显示调试”,这样才能在手柄上看到代表其指向的一条红色射线。但最关键的问题是,这个显示调试信息的功能只属于Debug调试模式,也就是说,一旦将项目正式打包发布,这条射线辅助线就没有了。如下图所示:我就觉得Unreal官方真的是有点过分了,这不应该是最基本的功能么?难道我们VR要在Debug模式下发布?

TxNet 1614

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

知识梳理——JavaScript

1. 说说前端中的事件流 HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件onclick、页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念。 什么是事件流:事件流描述的是从页面中接收事件的顺序. DOM2级事件流包括下面几个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段 addEventListener:addEventListener 是DOM2 级事件新增的指定事件处

wytraining 1632

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Vue里createElement 参数详解

createElement参数 接下来你需要熟悉的是如何在createElement函数中使用模板中的那些功能。这里是createElement接受的参数: // @returns {VNode} createElement( // {String | Object | Function} // 一个 HTML 标签名、组件选项对象,或者 // resolve 了上述任...

細水、長流√的专栏 6万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

vue2.x的h函数(createElement)与vue3中的h函数

在此你可以对比vue2与vue3中h函数的区别;vue2.x的 h 函数基础介绍及使用(createElement)及vue3中h函数的各种方法使用介绍

仙途路漫漫其修远兮 1万+

【vue2源码学习】— createElement

vue createElement发生了什么

kyyius的博客 1013

Vue 2.0源码分析-createElement

我们大致了解了 createElement 创建 VNode 的过程,每个 VNode 有 children,children 每个元素也是一个 VNode,这样就形成了一个 VNode Tree,它很好的描述了我们的 DOM Tree。回到 mountComponent 函数的过程,我们已经知道 vm._render 是如何创建了一个 VNode,接下来就是要把这个 VNode 渲染成一个真实的 DOM 并渲染出来,这个过程是通过 vm._update 完成的,接下来分析一下这个过程。

分享前端工程化、AI 应用、Agent 开发与大模型实践! 1702

vue的h函数(在 Vue 2中也称为 createElement)理解

摘要:h函数是Vue中用于创建虚拟节点(VNode)的核心API,接收元素类型、属性和子节点三个参数。它支持手动编写灵活的渲染逻辑,适用于组件库开发、性能优化等场景。Vue2中使用createElement,Vue3直接引入h函数。其原理是通过规范化参数并构建VNode对象,配合diff算法实现高效DOM更新。常见应用包括动态内容渲染、JSX转换和无模板组件开发,能精确控制DOM结构并优化渲染性能。(149字)

lzping_719的专栏 2559

vue通过$createElement创建节点渲染

vue通过$createElement创建节点渲染

weixin_48082595的博客 2652

【高级篇 / VDOM】(5.6) ❀ 01. 创建 VDOM 虚拟域 ❀ FortiGate 防火墙

【简介】虚拟域(VDOM),可以理解为虚拟防火墙,是一种将一台设备分为两个或两个以上虚拟设备的技术,它能起到多个独立设备的作用。VDOM可提供单独防火墙策略,在NAT/路由模式下,它可完全分开配置,从而为各连通网络或组织提供路由或VPN服务,同时VDOM之间也可以互访。设备的系统资源可以手动分配给不同的VDOM。一般常用于需要完成独立分割的多个网络,比如云环境。 ......

防火墙技术专栏 2万+

虚拟dom (virtual dom)(vnode)

1,虚拟DOM的逻辑(React虚拟dom到真实dom发生了什么) 2,React16 更新了什么 React16中引入了Fiber这个概念,从根本上解决了由于js的单线程运行,遇到计算量较大的情况,导致动画和交互卡顿的问题。 Fiber的核心是实现了一个基于优先级和requestIdleCallback的循环任务调度算法 。它可以把一个任务拆分成多个小任务,并且可随时中止或恢复任务,同时也可以...

yiyueqinghui的博客 2万+

Vue2.x中的Render函数

Render函数是Vue2.x版本新增的一个函数;使用虚拟dom来渲染节点提升性能,因为它是基于JavaScript计算。通过使用createElement(h)来创建dom节点。createElement是render的核心方法。其Vue编译的时候会把template里面的节点解析成虚拟dom; 什么是虚拟dom? 虚拟dom不同于真正的dom,它是一个JavaScript对象。当...

dc1339485的博客 699

vue2 render属性调用createElement()方法插入多级元素举例

h为接收的createElement()方法参数,[span]表示div为el-tooltip的子元素,子元素用数组包裹。

优快云wangyi的博客 562
上一篇: Vue2源码梳理:render函数的实现
下一篇: Vue2源码梳理:update的整体实现流程
Wang's Blog
博客等级 码龄12年 7434粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值