/* @flow */

import {
warn,
nextTick,
toNumber,
_toString,
looseEqual,
emptyObject,
handleError,
looseIndexOf
} from '../util/index' import VNode, {
cloneVNodes,
createTextVNode,
createEmptyVNode
} from '../vdom/vnode' import { createElement } from '../vdom/create-element'
import { renderList } from './render-helpers/render-list'
import { renderSlot } from './render-helpers/render-slot'
import { resolveFilter } from './render-helpers/resolve-filter'
import { checkKeyCodes } from './render-helpers/check-keycodes'
import { bindObjectProps } from './render-helpers/bind-object-props'
import { renderStatic, markOnce } from './render-helpers/render-static'
import { resolveSlots, resolveScopedSlots } from './render-helpers/resolve-slots' export function initRender (vm: Component) {
vm.$vnode = null // the placeholder node in parent tree 站位节点
vm._vnode = null // the root of the child tree 根节点
vm._staticTrees = null
const parentVnode = vm.$options._parentVnode
const renderContext = parentVnode && parentVnode.context
vm.$slots = resolveSlots(vm.$options._renderChildren, renderContext)
vm.$scopedSlots = emptyObject
// 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 templates
// 把创建元素 的函数绑定到这个实例上, 这样就能得到合适的渲染上下文;
// 参数的顺序是: 标签 数据 子节点 规范化的类型 是否总是规范化
vm._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)
} export function renderMixin (Vue: Class<Component>) {
//定义 $nextTick函数, 实际调用了 nextTick方法
Vue.prototype.$nextTick = function (fn: Function) {
return nextTick(fn, this)
} Vue.prototype._render = function (): VNode {
const vm: Component = this
const {
render,
staticRenderFns,
_parentVnode
} = vm.$options if (vm._isMounted) {
// clone slot nodes on re-renders
for (const key in vm.$slots) {
//克隆虚拟节点给自己
vm.$slots[key] = cloneVNodes(vm.$slots[key])
}
}

//scopedSlots ...
vm.$scopedSlots = (_parentVnode && _parentVnode.data.scopedSlots) || emptyObject if (staticRenderFns && !vm._staticTrees) {
vm._staticTrees = []
}
// set parent vnode. this allows render functions to have access
// to the data on the placeholder node.
  // 设置父虚拟节点, 这使得渲染函数可以访问站位节点上的数据 vm.$vnode = _parentVnode
// render self
let vnode
try {
vnode = render.call(vm._renderProxy, vm.$createElement)
} catch (e) {
handleError(e, vm, `render function`)
// return error render result,
// or previous vnode to prevent render error causing blank component
/* istanbul ignore else */
    // 返回一个错误渲染的结果, 或者前一个虚拟节点放在呈现错误的时候引起空白组件
if (process.env.NODE_ENV !== 'production') {
vnode = vm.$options.renderError
? vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e)
: vm._vnode
} else {
vnode = vm._vnode
}
}
// return empty vnode in case the render function errored out
// 返回空的虚拟节点 假如渲染函数出错了
if (!(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 parent
vnode.parent = _parentVnode
return vnode
} // internal render helpers.
// these are exposed on the instance prototype to reduce generated render
// code size.
// 用简写, 生成实例的时候减少代码
Vue.prototype._o = markOnce
Vue.prototype._n = toNumber
Vue.prototype._s = _toString
Vue.prototype._l = renderList
Vue.prototype._t = renderSlot
Vue.prototype._q = looseEqual
Vue.prototype._i = looseIndexOf
Vue.prototype._m = renderStatic
Vue.prototype._f = resolveFilter
Vue.prototype._k = checkKeyCodes
Vue.prototype._b = bindObjectProps
Vue.prototype._v = createTextVNode
Vue.prototype._e = createEmptyVNode
Vue.prototype._u = resolveScopedSlots
}

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. 【Thinking in Java, 4e】初始化与清理

    [用构造器确保初始化] [方法重载] 涉及基本类型的重载 1.如果传入的数据类型小于方法中声明的形式参数类型:实际数据类型会被提升. 2.如果传入的数据类型大于方法中声明的形式参数类型:编译器报错,应 ...

  2. DevOps实践之持续集成Jenkins(最新版本测试)

    一.安装Jenkins (1)下载并安装配置Java Development Kit 8 [root@localhost ~]# rpm -ivh jdk-8u161-linux-x64.rpm Pr ...

  3. 照着官网来安装openstack pike之创建并启动instance

    有了之前组件(keystone.glance.nova.neutron)的安装后,那么就可以在命令行创建并启动instance了 照着官网来安装openstack pike之environment设置 ...

  4. RocEDU.阅读.写作《苏菲的世界》书摘(五)

    在谈到如何获取确实的知识时,当时许多人持一种全然怀疑的论调,认为人应该接受自己一无所知事实.但笛卡尔却不愿如此.他如果接受这个事实,那他就不是一个真正的哲学家了.他的态度就像当年苏格拉底不肯接受诡辩学 ...

  5. 组播的介绍以及CS模型实现

    1.组播介绍 组播组可以是永久的也可以是临时的.组播组地址中,有一部分由官方分配的,称为永久组播组. 永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化.永久组播组中成员的数量都可以是任意 ...

  6. uboot源码中"include/configs/$(boardname).h"与"configs/$(boardname)_defconfig"之间有何异同

    答:最大的不同就是"configs/boardname_defconfig"中的选项都可以在make menuconfig中进行配置,而"include/configs/ ...

  7. tornado之WebSocket

    WebSocket WebSocket是HTML5规范中新提出的客户端-服务器通讯协议,协议本身使用新的ws://URL格式. WebSocket 是独立的.创建在 TCP 上的协议,和 HTTP 的 ...

  8. HDU5324 cqd分治

    HDU5324 cqd分治 标签(空格分隔): 未分类 给你两个长度相同数列,求第一个不上升,第二个不下降的最长子序列长度. 这里要求的子序列对第一个和第二个来说是相同的.即如果你在第一个序列里选了第 ...

  9. DataTable扩展:转化实体ToList

    直接上代码: 根据属性进行映射:DataTable转化成实体List public static class DataTableExtension { public static List<T& ...

  10. Grunt Part 2

    Objectives and Outcomes In this exercise, you will continue to learn to use Grunt, the task runner. ...