Vue3源码梳理:运行时之基于h函数生成vnode的内部流程

【Vue3源码学习】— CH3.2 VNode解析(上) 在 Vue 3 中,VNode(虚拟节点)是框架内部用于表示真实 DOM 结构的 JavaScript 对象。VNode 使得 Vue 能够在不直接操作 DOM 的情况下,通过比较新旧 VNode 来决定是否需要更新 DOM。这种机制提高了渲染性能,并简化了数据与视图之间的同步过程。 阅读详情

VNode 节点类型

  • 对于vnode而言,具备很多节点类型
  • vue源码中patch函数switch处理包含了好几种类型,常见类型如下
    • Text:文本节点
    • Comment:注释节点
    • Static:静态dom节点
    • Fragment:包含多个根节点的模板被表示为一个片段 fragment
    • ELEMENT:DOM 节点
    • COMPONENT:组件
    • TELEPORT:新的内置组件
    • SUSPENSE:新的内置组件
    • …

h函数源码解析

1 )使用 h 函数,示例demo程序

<script src='../../dist/vue.global.js'></script>

<div id='app'></div>

<script>
  const { h } = Vue
  const vnode = h('div', {
    class: 'test'
  }, 'hello render')
  console.log('vnode: ', vnode)
</script>

2 )对源码进行debug, 进入h函数

// Actual implementation
export function h(type: any, propsOrChildren?: any, children?: any): VNode {
  const l = arguments.length
  if (l === 2) {
    if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
      // single vnode without props
      if (isVNode(propsOrChildren)) {
        return createVNode(type, null, [propsOrChildren])
      }
      // props without children
      return createVNode(type, propsOrChildren)
    } else {
      // omit props
      return createVNode(type, null, propsOrChildren)
    }
  } else {
    if (l > 3) {
      children = Array.prototype.slice.call(arguments, 2)
    } else if (l === 3 && isVNode(children)) {
      children = [children]
    }
    return createVNode(type, propsOrChildren, children)
  }
}

h 函数需要三个参数: type, propsOrChildren, children

  • 注意第二个参数,propsOrChildren 是一个对象,它可以是props也可以是children
  • 内部是基于传入的长度和类型来判断的,先长度(先基于2来判断的)后类型
  • 最终返回 createVNode
  • h函数本身只是对用户传递的参数的处理,其本质是 createVNode
  • 使得 createVNode调用时,更加的方便

3 ) createVNode 源码


export const createVNode = (
  __DEV__ ? createVNodeWithArgsTransform : _createVNode
) as typeof _createVNode

function _createVNode(
  type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT,
  props: (Data & VNodeProps) | null = null,
  children: unknown = null,
  patchFlag: number = 0,
  dynamicProps: string[] | null = null,
  isBlockNode = false
): VNode {
  if (!type || type === NULL_DYNAMIC_COMPONENT) {
    if (__DEV__ && !type) {
      warn(`Invalid vnode type when creating vnode: ${type}.`)
    }
    type = Comment
  }

  if (isVNode(type)) {
    // createVNode receiving an existing vnode. This happens in cases like
    // <component :is="vnode"/>
    // #2078 make sure to merge refs during the clone instead of overwriting it
    const cloned = cloneVNode(type, props, true /* mergeRef: true */)
    if (children) {
      normalizeChildren(cloned, children)
    }
    if (isBlockTreeEnabled > 0 && !isBlockNode && currentBlock) {
      if (cloned.shapeFlag & ShapeFlags.COMPONENT) {
        currentBlock[currentBlock.indexOf(type)] = cloned
      } else {
        currentBlock.push(cloned)
      }
    }
    cloned.patchFlag |= PatchFlags.BAIL
    return cloned
  }

  // class component normalization.
  if (isClassComponent(type)) {
    type = type.__vccOpts
  }

  // 2.x async/functional component compat
  if (__COMPAT__) {
    type = convertLegacyComponent(type, currentRenderingInstance)
  }

  // class & style normalization.
  if (props) {
    // for reactive or proxy objects, we need to clone it to enable mutation.
    props = guardReactiveProps(props)!
    let { class: klass, style } = props
    if (klass && !isString(klass)) {
      props.class = normalizeClass(klass)
    }
    if (isObject(style)) {
      // reactive state objects need to be cloned since they are likely to be
      // mutated
      if (isProxy(style) && !isArray(style)) {
        style = extend({}, style)
      }
      props.style = normalizeStyle(style)
    }
  }

  // encode the vnode type information into a bitmap
  const shapeFlag = isString(type)
    ? ShapeFlags.ELEMENT
    : __FEATURE_SUSPENSE__ && isSuspense(type)
    ? ShapeFlags.SUSPENSE
    : isTeleport(type)
    ? ShapeFlags.TELEPORT
    : isObject(type)
    ? ShapeFlags.STATEFUL_COMPONENT
    : isFunction(type)
    ? ShapeFlags.FUNCTIONAL_COMPONENT
    : 0

  if (__DEV__ && shapeFlag & ShapeFlags.STATEFUL_COMPONENT && isProxy(type)) {
    type = toRaw(type)
    warn(
      `Vue received a Component which was made a reactive object. This can ` +
        `lead to unnecessary performance overhead, and should be avoided by ` +
        `marking the component with \`markRaw\` or using \`shallowRef\` ` +
        `instead of \`ref\`.`,
      `\nComponent that was made reactive: `,
      type
    )
  }

  return createBaseVNode(
    type,
    props,
    children,
    patchFlag,
    dynamicProps,
    shapeFlag,
    isBlockNode,
    true
  )
}
  • 其本质上触发的是 _createVNode,进入它,有6个参数
  • type, props, children, patchFlag, dynamicProps, isBlockNode,我们主要关注其中三个参数
    • type
    • props
    • children
  • 代码往下走,看下 isVNode 函数,判断比较简单
    • return value ? value.__v_isVNode === true: false
    • 就是根据value的属性来的
  • 之后在判断是否是class
  • 在之后判断 props,这里执行
    • guardReactiveProps(props) 解析props的逻辑暂时不去管它
      • vue会有class和style的增强,这块先不去管它
  • 之后走到一个比较复杂的三目运算 shapeFlag
  • 它本身是一个枚举类,定义了很多类型
  • 代码继续执行,直到 return createBaseVNode

createBaseVNode 函数

function createBaseVNode(
  type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT,
  props: (Data & VNodeProps) | null = null,
  children: unknown = null,
  patchFlag = 0,
  dynamicProps: string[] | null = null,
  shapeFlag = type === Fragment ? 0 : ShapeFlags.ELEMENT,
  isBlockNode = false,
  needFullChildrenNormalization = false
) {
  const vnode = {
    __v_isVNode: true,
    __v_skip: true,
    type,
    props,
    key: props && normalizeKey(props),
    ref: props && normalizeRef(props),
    scopeId: currentScopeId,
    slotScopeIds: null,
    children,
    component: null,
    suspense: null,
    ssContent: null,
    ssFallback: null,
    dirs: null,
    transition: null,
    el: null,
    anchor: null,
    target: null,
    targetAnchor: null,
    staticCount: 0,
    shapeFlag,
    patchFlag,
    dynamicProps,
    dynamicChildren: null,
    appContext: null
  } as VNode

  if (needFullChildrenNormalization) {
    normalizeChildren(vnode, children)
    // normalize suspense children
    if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) {
      ;(type as typeof SuspenseImpl).normalize(vnode)
    }
  } else if (children) {
    // compiled element vnode - if children is passed, only possible types are
    // string or Array.
    vnode.shapeFlag |= isString(children)
      ? ShapeFlags.TEXT_CHILDREN
      : ShapeFlags.ARRAY_CHILDREN
  }

  // validate key
  if (__DEV__ && vnode.key !== vnode.key) {
    warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type)
  }

  // track vnode for block tree
  if (
    isBlockTreeEnabled > 0 &&
    // avoid a block node from tracking itself
    !isBlockNode &&
    // has current parent block
    currentBlock &&
    // presence of a patch flag indicates this node needs patching on updates.
    // component nodes also should always be patched, because even if the
    // component doesn't need to update, it needs to persist the instance on to
    // the next vnode so that it can be properly unmounted later.
    (vnode.patchFlag > 0 || shapeFlag & ShapeFlags.COMPONENT) &&
    // the EVENTS flag is only for hydration and if it is the only flag, the
    // vnode should not be considered dynamic due to handler caching.
    vnode.patchFlag !== PatchFlags.HYDRATE_EVENTS
  ) {
    currentBlock.push(vnode)
  }

  if (__COMPAT__) {
    convertLegacyVModelProps(vnode)
    defineLegacyVNodeProperties(vnode)
  }

  return vnode
}
  • 进入这个函数
    • type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, needFullChildrenNormalization
    • 接下来,创建 vnode对象,包含
      • __v_isVNode
    • 这时候构建出了一个初始的vnode对象
      • 初始化很多属性,我们只需要关注对我们有用的
  • 继续执行,到 normalizeChildren(vnode, children)
    • 这个函数里面涉及到一个 进位符 & 和 按位或赋值 |=
    • |= 这里是按位或运算
    • 这里展开下:
      • 10进制的1转换成二进制是: 01,
      • 10(2) === 2(10) 括号里面是进制
      • 在vue的运算里,其实他们都是32位的
    • 32位是指有32个比特位
      • 00000000 00000000 00000000 00000000
    • 二进制的1是:
      • 00000000 00000000 00000000 00000001
      • 当前调试debug的flag的值,10进制是1,也是如上表示
    • 二进制的8是:
      • 00000000 00000000 00000000 00001000
    • 上述1和8执行或运算(有一个1则是1),得到
      • 00000000 00000000 00000000 00001001

总结下

  • h函数本质上是处理一个参数的问题
  • 核心代码是在 _createVNode 中进行的
  • 里面生成vnode的核心方法,做了一件重要的事情是构建了一个 shapeFlag
  • 第一次构建的时候,它的flag是ELEMENT类型
  • 接下来return 了 createBaseVNode 函数
  • 它根据 type, props, children,shapeFlag 生成了一个 vnode 节点
  • 通过按位或运算,来改变flag的值,重新赋值给 shapeFlag
  • 最终 return vnode 对象
Vue3学习之旅--Composition API--高级篇--render和h函数以及jsx的使用 文章目录Composition API(三) 及高级语法补充生命周期钩子Provide函数Inject函数数据的响应式修改响应式Propertyscript setup实验性特性setup顶层写法认识h函数h()函数 如何使用呢?h函数的基本使用h函数计数器案例1. render函数实现2. setup函数实现函数组件和插槽的使用jsx的babel配置jsx的基本使用和计数器案例 vue3笔记 vue3学习之旅–邂逅vue3-了解认识Vue3 vue3学习之旅–邂逅vue3-了解认识Vue3(二) Vue3 阅读详情

相关推荐

【Vue3源码学习】— CH3.2 VNode解析(下)

此过程涉及多种类型的输入处理,如文本、数组、插槽等,每种类型都有特定的处理逻辑来确保 VNode 正确反映了组件或元素的预期结构。总结来说,VNode 的创建和处理是 Vue 渲染机制的核心部分,它不仅涉及到数据结构的建立,还包括性能优化措施,以确保应用的响应性和效率。因为 VNode 是独立于浏览器 DOM 的,所以 Vue 可以在不同的环境中运行,如服务器端渲染(SSR)或原生移动应用,这是通过项目如 Vue Native 或 Weex 实现的。最终的结果是,App 组件被成功渲染到了页面上。

YSG的博客 1178

Vue3 学习笔记 —— 函数式编程、createVNode、render、h 函数

Vue3 学习笔记 —— 函数式编程、createVNode、render、h 函数

Lyrelion的博客 1万+

【ChatGPT带你学Vue】Vue3 核心源码解析(1)createApp 、h函数、nextTick

首先安利一个非常好用的小站,清晰地梳理了Vue3源码的一些核心模块,结合ChatGPT插件的代码解释功能一起阅读,无比丝滑!下面就记录一下AI帮我分析的源码相关内容。

m0_37406045的博客 1577

Vue3中的VNode是什么?它的工作原理是什么?

VNode 全称 Virtual Node,翻译过来就是虚拟节点。它是对真实 DOM 的一个抽象表示。简单来说,VNode 是一个描述 DOM 结构的 JavaScript 对象,而不是实际的 DOM 元素。VNode 是 Vue 3 中虚拟 DOM 的核心概念,通过对真实 DOM 的抽象表示,VNode 提供了高效的视图更新机制。VNode 的工作流程主要包括创建、更新和渲染三个步骤。理解这些过程有助于我们更好地开发 Vue 应用和调试性能问题。web前端高频面试题_在线视频教程-优快云程序员研修院。

有我更精彩的博客 3192

Vue 3源码极客之:`Vue`的`teleport`:其在`VNode`树中的处理方式。

是Vue 3里一个非常实用的组件,可以用来解决组件内容渲染位置的问题。它可以把组件的内容传送到DOM树的另一个位置,避免被父组件的样式所影响。别看它名字像科幻电影里的瞬间移动,其实它干的事儿也差不多——能把组件的内容“传送”到DOM树的另一个地方。会把组件的内容传送到DOM树的另一个位置,所以可能会导致样式问题。就像一个DOM传送门,让你把组件的内容送到指定的地点。的内容依赖于父组件的样式,可能会出现样式失效的情况。的内容会渲染在原来的位置,而不是传送到目标元素下。的内容渲染到指定的目标位置。

weixin_41455464的博客 590

OpenCompass实战:从零部署大模型评测平台,量化模型能力选型

在大模型技术选型与评估中,客观、可量化的评测体系是工程实践的关键。其核心原理在于通过标准化的数据集、统一的评测方法与自动化流程,将主观的模型体验转化为可比较的指标数据。这种评测框架的技术价值在于解决了模型能力评估的模糊性问题,为开发者提供了模型选型、效果对比与迭代优化的科学依据。典型的应用场景包括对比不同开源模型在代码生成、逻辑推理等特定任务上的性能,或是评估微调后模型在业务数据集上的提升效果。OpenCompass作为开源的大模型全能力评测平台,正是这一理念的工程化实现。它通过模块化的四层流水线架构和配置

weixin_28725037的博客 630

Vue3源码梳理:运行时的设计方案概况

在运行时 runtime ,渲染器 renderer 会遍历整个虚拟dom树,并据此结构构建真实的dom树这个过程我们可以把它叫做挂载 mount在这个 vnode 对象发生变化时候,我们会对比 旧的 VNode 和 新的 VNode 之间的区别找出它们之间的区别,并应用这其中的变化到真实的dom上,这个过程叫做更新 patch。

Wang的专栏 313

在Windows11上安装ubuntu版linux系统并实现桌面图形化(WSL)

在Windows11上安装ubuntu版linux系统并实现桌面图形化(WSL),xfce桌面美化、安装google-chrome

NiKoJJ‘s Blog 1万+

Vue之render构建、调用整体流程

前言 本篇文章是想要探寻下Vue中是如何处理html到vnode以及vnode转换为html的过程,主要是梳理其大概流程,一些细节流程会在单独文章的细究。

玉案轩窗的博客 3661

【NLP】语言模型的发展历程 (1)

N-gram模型是一种基于统计语言模型的文本分析算法,它用于预测文本中下一个词出现的概率,基于前面出现的n-1个词的序列。这里的n代表序列中元素的数量,因此称为N-gram。Unigram:N=1,每个单词的出现概率独立计算,不考虑上下文。Bigram:N=2,基于前一个单词预测当前单词的联合概率模型。Trigram:N=3,考虑前两个单词来预测当前单词的联合概率模型,更复杂但可能更准确。

酒酿小圆子呀~ 1670

从零到一:KUKA机械臂与ROS的工业级通讯协议深度解析

本文深度解析KUKA机械臂与ROS的工业级通讯协议,重点对比EKI与RSI两种核心接口的技术特点与应用场景。详细介绍了网络架构设计、数据包解析机制及ROS-I集成方法,并提供实时性能优化与故障排除策略,为工程师实现高可靠性工业自动化集成提供完整解决方案。

2a4s6d8f0g的博客 296

Vue源码:虚拟DOM和diff算法(2),学习路线+知识点梳理

h函数用来产生虚拟节点h函数用来产生比如这样会调用h函数将得到这样的虚拟节点“data”: {props: {},“text”: “尚硅谷”它表示的真正DOM节点一个虚拟节点都有哪些属性children: undefined, // 子元素data: {}, // 属性、样式elm: undefined, // 对应真正DOM节点,如果为undefined,表示该节点还未上树key: undefined, // 节点唯一标识sel: “div”, // 选择器。

2401_84097520的博客 1071

MBD-从一个示例看代码生成过程(rtw文件、TLC语言)

大概介绍了MBD代码生成流程,rtw文件、TLC语言

小胡同学的工程师学习之路 4214

Vue实例之render构建+调用

前言 前几篇文章分析了Vue初始化以及Vue实例创建时data、computed、$mount相关的处理,引出了Vue响应式原理的实现以及computed与data不同的处理。 本篇文章是想要探寻下Vue中是如何处理html到vnode以及vnode转换为html的过程,之后会结合Moon.js中关于此过程的处理,比较二者的区别。 而这篇文章的初衷是想要结合此处的实现逻辑,自实现下简易的MV...

細水、長流√的专栏 605

8、干式变压器

干式变压器的发展,是人类不断挑战材料科学和热物理极限的过程,每一次技术突破,都是在。温度升高,ε_r反而下降(因为分子活动性增强,极化响应变慢)。:固体导热的热阻比液体对流大一个数量级,这是无法逾越的物理规律。Nomex在高温下不是逐渐分解,而是保持性能直到一个临界点。如果 T_a = 40°C,则 T_c = 146.7°C。干式变压器(固体介质分隔):热场、电场、流场(空气)形成三维氢键网络,即使在高温下也能保持机械强度。:不是在现有技术上修修补补,而是寻找新的。仍在H级绝缘允许范围内(≤180°C)

renpeng2692873032的博客 230

超导电动悬浮系统一体化地面线圈电-热-力特性研究——基于ANSYS Maxwell与Workbench的多物理场联合仿真

摘要:超导电动悬浮(EDS)系统的地面线圈在运行中面临电-热-力多物理场强耦合挑战。本文基于ANSYS Maxwell和Workbench平台,提出一套联合仿真方法,对地面线圈进行高保真多物理场耦合分析。研究通过建立参数化三维电磁模型,计算瞬态涡流损耗和电磁力分布,并顺序耦合至热分析和结构分析,揭示电-热-力特性的相互影响机制。该方法为地面线圈的优化设计、材料选型和可靠性评估提供了理论依据和仿真工具支撑。 关键词:超导电动悬浮;地面线圈;多物理场耦合;联合仿真;ANSYS

huanghm88的专栏 376

Element Plus Notification组件HTML渲染失效的深度诊断与修复指南:终极解决方案

Element Plus作为基于Vue 3的企业级UI组件库,其Notification组件是前端开发中常用的全局通知工具。然而,当开发者尝试渲染HTML内容时,经常会遇到HTML标签被转义显示为纯文本的问题,这影响了通知消息的丰富性和用户体验。本文将深入探讨Element Plus Notification组件HTML渲染失效的根本原因,并提供完整的诊断与修复方案。 ## 🔍 Notific

gitblog_00519的博客 922

YOLOv11改进 | 注意力篇 | YOLOv11引入CA注意力机制

摘要:最近关于移动网络设计的研究已经证明了通道注意力(例如,挤压和激励注意力)对于提升模型性能的显着有效性,但它们通常忽略了位置信息,而位置信息对于生成空间选择性注意力图很重要。到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv11改进有效涨点专栏,本专栏目前为新开的,后期我会根据各种前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~3.2 在Extramodule里创建CA。在CA.py文件里添加给出的CA代码。

tsg6698的博客 2981

vue实践之路

npm install -g vue-cli vue init webpack vue_demo cd vue_demo npm install npm run dev 访问:http://localhost:8080/

michael_linux的博客,一个小小小学生。滴水穿石,步步为营,只为那刹那芳华。 454

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

带你看懂Virtual DOM及diff算法在vue中的应用

什么是vdom vdom 是一种使用js对象来描述真实dom的技术,通过这种,我们能精确知道哪些真实的Dom改变了,从而尽量减少Dom操作的性能开销。 snabbdom.js vdom是通过snabbdom.js库实现的,大概过程有以下三部 1.compile (把真实的dom编译成Vnode); 2.diff (利用diff算法,比较oldVnode和newVnode之间有什么变化); 3.patch(把这些变化通过打补丁的方式更新到真实的dom上去); snabbdom的两个核心函

weixin_44389107的博客 519

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Vue 完整版系统知识文档

《Vue全栈开发实战手册》摘要 本手册系统整合Vue2/Vue3全栈知识体系,涵盖基础语法、组件开发、状态管理、工程化等核心内容,适合从入门到精通的完整学习路径。主要特点: 基础核心 详解MVVM架构和响应式原理(Vue2的Object.defineProperty vs Vue3的Proxy) 完整模板语法规则与16种内置指令解析 组件系统核心:通信机制(8种方案)、插槽、动态组件、递归组件 进阶实战 状态管理:Vuex/Pinia完整解决方案 路由开发:动态路由、权限控制、懒加载 工程化:Webpack

专注 Java 后端开发,分享基础语法、JVM、并发、Spring 全家桶、微服务、分布式、性能优化等实战干货。坚持输出高质量技术笔记,用简单语言讲清复杂原理,助力每一位 Java 开发者稳步进阶。 402

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain&#39;s apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath(&#39;DeepLearnToolbox&#39;));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand(&#39;state&#39;,0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W&#39;); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand(&#39;state&#39;,0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = &#39;sigm&#39;;%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, &#39;Too big error&#39;);```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand(&#39;state&#39;,0)sae = saesetup([784 100]);sae.ae{1}.activation_function = &#39;sigm&#39;;sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)&#39;)% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = &#39;sigm&#39;;nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, &#39;Too big error&#39;);```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x&#39;,28,28,60000))/255;test_x = double(reshape(test_x&#39;,28,28,10000))/255;train_y = double(train_y&#39;);test_y = double(test_y&#39;);%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you&#39;ll get around 1.2% errorrand(&#39;state&#39;,0)cnn.layers = { struct(&#39;type&#39;, &#39;i&#39;) %input layer struct(&#39;type&#39;, &#39;c&#39;, &#39;outputmaps&#39;, 6, &#39;kernelsize&#39;, 5) %convolution layer struct(&#39;type&#39;, &#39;s&#39;, &#39;scale&#39;, 2) %sub sampling layer struct(&#39;type&#39;, &#39;c&#39;, &#39;outputmaps&#39;, 12, &#39;kernelsize&#39;, 5) %convolution layer struct(&#39;type&#39;, &#39;s&#39;, &#39;scale&#39;, 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, &#39;Too big error&#39;);```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, &#39;Too big error&#39;);%% ex2 neural net with L2 weight decayrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex3 neural net with dropoutrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex4 neural net with sigmoid activation functionrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);nn.activation_function = &#39;sigm&#39;; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex5 plotting functionalityrand(&#39;state&#39;,0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = &#39;softmax&#39;; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand(&#39;state&#39;,0)nn = nnsetup([784 20 10]); nn.output = &#39;softmax&#39;; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

vue笔记

监听字符串、数字、布尔值等简单数据类型时,直接在watch中定义与数据同名的属性,属性值为处理函数(接收两个参数:新值newVal和旧值oldValdata() {return {username: '', // 简单数据age: 18},watch: {// 监听 username 的变化console.log('用户名从', oldVal, '变成了', newVal);},// 监听 age 的变化。

2301_79775040的博客 4299

前端框架 Diff 算法(文章)

面试中经常被问到框架 Diff 算法,下面梳理下 Diff 算法相关知识点。首先,用一个 JS 对象模拟 DOM 结构,即 vnode,然后 h 函数是用于生成一个 vnode 的,里面包含元素选择器 sel、子节点 children、key 等属性。

u012578908的博客 440

Vue与React高频面试题全收录,前端程序员节刷题必备清单

掌握Vue与React高频面试题,助力前端程序员节刷题突破技术瓶颈。涵盖组件通信、生命周期、虚拟DOM等核心知识点,结合真实面试场景解析解题思路,提升应试能力。大厂常考题型一网打尽,值得收藏。

AlgoInk的博客 363

VUE2常见面试题

本文摘要: Vue相关技术核心概念解析 MVVM与MVC架构区别 MVC单向数据流,视图与控制器耦合 MVVM双向绑定,数据自动同步,解耦视图与模型 Vue核心特性 生命周期钩子函数执行顺序(8个阶段) 数据双向绑定原理(Object.defineProperty+发布订阅) 组件通信机制(父子props/emit、跨级provide/inject等) 虚拟DOM与diff算法优化渲染 计算属性与侦听器区别(缓存机制) 状态管理 Vuex工作流程(state/mutations/actions/getter

2301_76805327的博客 467

前端老铁别硬刚:虚拟DOM到底咋让页面丝滑如德芙(附避坑指南)

写这篇文章的时候,我翻了不少源码,也回想了自己这些年前端路上的踩坑史。说实话,虚拟DOM确实是个巧妙的设计,但它只是特定历史时期的特定解决方案。它解决的是"频繁操作DOM性能差"的问题,但带来的代价是额外的抽象层、内存占用和计算开销。现在浏览器越来越智能,比如Chrome的属性可以跳过屏幕外元素的渲染,Web Components提供了更原生的组件化方案,甚至未来的"量子DOM"(如果真有人搞出来)可能会让虚拟DOM变得多余。但不管技术怎么变,理解底层原理、具备调试和优化的能力永远是核心竞争力。

master_chenchen的博客 325
上一篇: Vue3源码梳理:运行时的设计方案概况
下一篇: Vue2源码梳理:关于静态类型检查工具flow
Wang's Blog
博客等级 码龄12年 7433粉丝 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、付费专栏及课程。

余额充值