1. /* @flow */
  2.  
  3. import {
  4. warn,
  5. nextTick,
  6. toNumber,
  7. _toString,
  8. looseEqual,
  9. emptyObject,
  10. handleError,
  11. looseIndexOf
  12. } from '../util/index'
  13.  
  14. import VNode, {
  15. cloneVNodes,
  16. createTextVNode,
  17. createEmptyVNode
  18. } from '../vdom/vnode'
  19.  
  20. import { createElement } from '../vdom/create-element'
  21. import { renderList } from './render-helpers/render-list'
  22. import { renderSlot } from './render-helpers/render-slot'
  23. import { resolveFilter } from './render-helpers/resolve-filter'
  24. import { checkKeyCodes } from './render-helpers/check-keycodes'
  25. import { bindObjectProps } from './render-helpers/bind-object-props'
  26. import { renderStatic, markOnce } from './render-helpers/render-static'
  27. import { resolveSlots, resolveScopedSlots } from './render-helpers/resolve-slots'
  28.  
  29. export function initRender (vm: Component) {
  30. vm.$vnode = null // the placeholder node in parent tree 站位节点
  31. vm._vnode = null // the root of the child tree 根节点
  32. vm._staticTrees = null
  33. const parentVnode = vm.$options._parentVnode
  34. const renderContext = parentVnode && parentVnode.context
  35. vm.$slots = resolveSlots(vm.$options._renderChildren, renderContext)
  36. vm.$scopedSlots = emptyObject
  37. // bind the createElement fn to this instance
  38. // so that we get proper render context inside it.
  39. // args order: tag, data, children, normalizationType, alwaysNormalize
  40. // internal version is used by render functions compiled from templates
    // 把创建元素 的函数绑定到这个实例上, 这样就能得到合适的渲染上下文;
    // 参数的顺序是: 标签 数据 子节点 规范化的类型 是否总是规范化
  41. vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
  42. // normalization is always applied for the public version, used in
  43. // user-written render functions.
    // 规范化总是应用在公共的版本, 应用在用户编写的 渲染函数
  44. vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)
  45. }
  46.  
  47. export function renderMixin (Vue: Class<Component>) {
    //定义 $nextTick函数, 实际调用了 nextTick方法
  48. Vue.prototype.$nextTick = function (fn: Function) {
  49. return nextTick(fn, this)
  50. }
  51.  
  52. Vue.prototype._render = function (): VNode {
  53. const vm: Component = this
  54. const {
  55. render,
  56. staticRenderFns,
  57. _parentVnode
  58. } = vm.$options
  59.  
  60. if (vm._isMounted) {
  61. // clone slot nodes on re-renders
  62. for (const key in vm.$slots) {
    //克隆虚拟节点给自己
  63. vm.$slots[key] = cloneVNodes(vm.$slots[key])
  64. }
  65. }

  66. //scopedSlots ...
  67. vm.$scopedSlots = (_parentVnode && _parentVnode.data.scopedSlots) || emptyObject
  68.  
  69. if (staticRenderFns && !vm._staticTrees) {
  70. vm._staticTrees = []
  71. }
  72. // set parent vnode. this allows render functions to have access
  73. // to the data on the placeholder node.
      // 设置父虚拟节点, 这使得渲染函数可以访问站位节点上的数据
  74.  
  75. vm.$vnode = _parentVnode
  76. // render self
  77. let vnode
  78. try {
  79. vnode = render.call(vm._renderProxy, vm.$createElement)
  80. } catch (e) {
  81. handleError(e, vm, `render function`)
  82. // return error render result,
  83. // or previous vnode to prevent render error causing blank component
  84. /* istanbul ignore else */
        // 返回一个错误渲染的结果, 或者前一个虚拟节点放在呈现错误的时候引起空白组件
  85. if (process.env.NODE_ENV !== 'production') {
  86. vnode = vm.$options.renderError
  87. ? vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e)
  88. : vm._vnode
  89. } else {
  90. vnode = vm._vnode
  91. }
  92. }
  93. // return empty vnode in case the render function errored out
    // 返回空的虚拟节点 假如渲染函数出错了
  94. if (!(vnode instanceof VNode)) {
  95. if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) {
  96. warn(
  97. 'Multiple root nodes returned from render function. Render function ' +
  98. 'should return a single root node.',
  99. vm
  100. )
  101. }
  102. vnode = createEmptyVNode()
  103. }
  104. // set parent
  105. vnode.parent = _parentVnode
  106. return vnode
  107. }
  108.  
  109. // internal render helpers.
  110. // these are exposed on the instance prototype to reduce generated render
  111. // code size.
    // 用简写, 生成实例的时候减少代码
  112. Vue.prototype._o = markOnce
  113. Vue.prototype._n = toNumber
  114. Vue.prototype._s = _toString
  115. Vue.prototype._l = renderList
  116. Vue.prototype._t = renderSlot
  117. Vue.prototype._q = looseEqual
  118. Vue.prototype._i = looseIndexOf
  119. Vue.prototype._m = renderStatic
  120. Vue.prototype._f = resolveFilter
  121. Vue.prototype._k = checkKeyCodes
  122. Vue.prototype._b = bindObjectProps
  123. Vue.prototype._v = createTextVNode
  124. Vue.prototype._e = createEmptyVNode
  125. Vue.prototype._u = resolveScopedSlots
  126. }

vue.js 源代码学习笔记 ----- instance render的更多相关文章

  1. vue.js 源代码学习笔记 ----- instance proxy

    /* not type checking this file because flow doesn't play well with Proxy */ import config from 'core ...

  2. vue.js 源代码学习笔记 ----- instance init

    /* @flow */ import config from '../config' import { initProxy } from './proxy' import { initState } ...

  3. vue.js 源代码学习笔记 ----- instance index

    import { initMixin } from './init' import { stateMixin } from './state' import { renderMixin } from ...

  4. vue.js 源代码学习笔记 ----- instance state

    /* @flow */ import Dep from '../observer/dep' import Watcher from '../observer/watcher' import { set ...

  5. vue.js 源代码学习笔记 ----- instance event

    /* @flow */ import { updateListeners } from '../vdom/helpers/index' import { toArray, tip, hyphenate ...

  6. vue.js 源代码学习笔记 ----- instance inject

    /* @flow */ import { hasSymbol } from 'core/util/env' import { warn } from '../util/index' import { ...

  7. vue.js 源代码学习笔记 ----- core lifecycle

    /* @flow */ import config from '../config' import Watcher from '../observer/watcher' import { mark, ...

  8. vue.js 源代码学习笔记 ----- html-parse.js

    /** * Not type-checking this file because it's mostly vendor code. */ /*! * HTML Parser By John Resi ...

  9. vue.js 源代码学习笔记 ----- keep-alives

    /* @flow */ import { callHook } from 'core/instance/lifecycle' import { getFirstComponentChild } fro ...

随机推荐

  1. BIOS/MBR UEFI/GPT关系与区别-资料整理

    ---恢复内容开始--- 关于 BIOS/MBR UEFI/GPT他们之间的关系一直比较疑惑, 首先一点前提 BIOS UEFI 是一类,是控制硬件,引导启动的:MBR GPT是硬盘的分区定义.. 后 ...

  2. vsftpd搭建ftp服务,并实现虚拟用户访问

    安装vsftpd服务: yum install vsftpd -y [root@wadeson ~]# rpm -ql vsftpd /etc/logrotate.d/vsftpd /etc/pam. ...

  3. 20145329 《Java程序设计》课程总结

    每周读书笔记链接汇总 •第一周读书笔记 http://www.cnblogs.com/jdy1453/p/5248592.html •第二周读书笔记 http://www.cnblogs.com/jd ...

  4. Excel水平线画不直,图形对象对不齐,怎么办

    看够了千篇一律的数字报表,不妨添加些图形对象来调剂下,今天小编excel小课堂(ID:excel-xiaoketang 长按复制)给各位分享10个插入图形对象时简单实用的小技巧. 01课题 今天小编e ...

  5. maven下载与配置环境变量

    1.打开maven官网下载 http://maven.apache.org/download.cgi 下载 解压(这里博主放在D盘下) 2.配置环境变量 验证是否配置成功 3.本地仓库配置

  6. 2017 ACM/ICPC Asia 南宁区 L The Heaviest Non-decreasing Subsequence Problem

    2017-09-24 20:15:22 writer:pprp 题目链接:https://nanti.jisuanke.com/t/17319 题意:给你一串数,给你一个处理方法,确定出这串数的权值, ...

  7. [笔记整理]SQL Server 索引碎片 和 重建索引

    铺垫知识点: 数据库存储本身是无序的,建立了聚集索引,会按照聚集索引物理顺序存入硬盘.既键值的逻辑顺序决定了表中相应行的物理顺序 多数情况下,数据库读取频率远高于写入频率,索引的存在 为了读取速度牺牲 ...

  8. [小问题笔记(四)] Enum枚举类型转换为DataTable( C# )

    枚举: public enum ProductType { 小产品=, 大产品, 超大产品 } 转换方法: /// <summary> /// 枚举类型转化为DataTable /// & ...

  9. 使用SoupUI进行简单的WebService接口测试

    1.工具介绍 SoapUI是一个开源测试工具,通过soap/http来检查.调用.实现Web Service的功能/负载/符合性测试.该工具既可作为一个单独的测试软件使用,也可利用插件集成到Eclip ...

  10. 微信公众平台开发(一) 配置接口与验证URL

    一.简介 微信公众平台是腾讯公司在微信的基础上新增的功能模块,通过这一平台,个人和企业都可以打造一个微信的公众号,并实现和特定群体的文字.图片.语音的全方位沟通.互动. 二.通讯机制 三.注册微信平台 ...