当前位置: 首页 > news >正文

Vue 2.0源码分析-渲染函数render

Vue 的 _render 方法是实例的一个私有方法,它用来把实例渲染成一个虚拟 Node。它的定义在 src/core/instance/render.js 文件中:

Vue.prototype._render = function (): VNode {const vm: Component = thisconst { render, _parentVnode } = vm.$options// reset _rendered flag on slots for duplicate slot checkif (process.env.NODE_ENV !== 'production') {for (const key in vm.$slots) {// $flow-disable-linevm.$slots[key]._rendered = false}}if (_parentVnode) {vm.$scopedSlots = _parentVnode.data.scopedSlots || emptyObject}// set parent vnode. this allows render functions to have access// to the data on the placeholder node.vm.$vnode = _parentVnode// render selflet vnodetry {vnode = render.call(vm._renderProxy, vm.$createElement)} catch (e) {handleError(e, vm, `render`)// return error render result,// or previous vnode to prevent render error causing blank component// istanbul ignore elseif (process.env.NODE_ENV !== 'production') {if (vm.$options.renderError) {try {vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e)} catch (e) {handleError(e, vm, `renderError`)vnode = vm._vnode}} else {vnode = vm._vnode}} else {vnode = vm._vnode}}// return empty vnode in case the render function errored outif (!(vnode instanceof VNode)) {if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) {warn('Multiple root nodes returned from render function. Render function ' +'should return a single root node.',vm)}vnode = createEmptyVNode()}// set parentvnode.parent = _parentVnodereturn vnode
}

这段代码最关键的是 render 方法的调用,我们在平时的开发工作中手写 render 方法的场景比较少,而写的比较多的是 template 模板,在之前的 mounted 方法的实现中,会把 template 编译成 render 方法,但这个编译过程是非常复杂的,之后会专门有一个章节来分析 Vue 的编译过程。

在 Vue 的官方文档中介绍了 render 函数的第一个参数是 createElement,那么结合之前的例子:

<div id="app">{{ message }}
</div>

相当于我们编写如下 render 函数:

render: function (createElement) {return createElement('div', {attrs: {id: 'app'},}, this.message)
}

再回到 _render 函数中的 render 方法的调用:

vnode = render.call(vm._renderProxy, vm.$createElement)

可以看到,render 函数中的 createElement 方法就是 vm.$createElement 方法:

export function initRender(vm: Component) {// bind the createElement fn to this instance// so that we get proper render context inside it.// args order: tag, data, children, normalizationType, alwaysNormalize// internal version is used by render functions compiled from templatesvm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)// normalization is always applied for the public version, used in// user-written render functions.vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)
}

实际上,vm.$createElement 方法定义是在执行 initRender 方法的时候,可以看到除了 vm.$createElement 方法,还有一个 vm._c 方法,它是被模板编译成的 render 函数使用,而 vm.$createElement 是用户手写 render 方法使用的, 这俩个方法支持的参数相同,并且内部都调用了 createElement 方法。

总结

vm._render 最终是通过执行 createElement 方法并返回的是 vnode,它是一个虚拟 Node。Vue 2.0 相比 Vue 1.0 最大的升级就是利用了 Virtual DOM。因此在分析 createElement 的实现前,需要先了解一下 Virtual DOM 的概念。

http://www.lryc.cn/news/249202.html

相关文章:

  • 阿里云国际短信业务网络超时排障指南
  • 浅用tensorflow天气预测
  • 基于SpringBoot学生读书笔记共享
  • 设计模式之装饰模式(2)--有意思的想法
  • 深入了解 Pinia:现代 Vue 应用的状态管理利器
  • TTS声音合成:paddlespeech、sherpa-onnx、coqui-ai
  • Android frameworks 开发总结之十一
  • 抑制过拟合——Dropout原理
  • 开发板启动进入系统以后再挂载 NFS 文件系统, 这里的NFS文件系统是根据正点原子教程制作的ubuntu_rootfs
  • Ubuntu系统执行“docker ps“出现“permission denied“
  • Python与设计模式--桥梁模式
  • Linux下查看目录大小
  • 鸿蒙原生应用/元服务开发-AGC分发如何下载管理Profile
  • 解决warning: #188-D: enumerated type mixed with another type问题
  • docker的知识点,以及使用
  • WTM(基于Blazor)问题处理记录
  • ubuntu 安装 towhee
  • ERP软件对Oracle安全产品的支持
  • Linux 基础-常用的命令和搭建 Java 部署环境
  • c语言总结(解题方法)
  • Webpack的ts的配置详细教程
  • 传智杯第五届题解
  • Android 通过demo调试节点权限问题
  • 邮政快递物流查询,将指定某天签收的单号筛选出来
  • Java 8 lambda的一个编译bug
  • 无人机覆盖路径规划综述
  • 【代码随想录】算法训练计划37
  • 网络基础_1
  • 机器学习:DBSCAN算法(效果比K-means好)
  • 在Spring Boot中隔离@Async异步任务的线程池