/* @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. [Linux 006]——grep和正则表达式

    在使用系统时,我们或多或少的有一些搜索.查找的需求,必须要在文本中搜索某个关键字,或者过滤出文本中某些特定的行.grep 命令就为我们提供了这样一个功能,同时,grep 还可以使用正则表达式进行匹配, ...

  2. 20145309《Java程序设计》第八周学习总结

    日志 •java.util.logging包提供了日志功能相关类与接口,使用日志的起点是logger类,Logger类的构造函数标示为protected,不是java.util.logging同包的类 ...

  3. MYSQL数据库里面的所有密码批量MD5加密

    如果你的字段够长度的话:UPDATE users SET password = MD5(password);如果长度不够,可以先增加长度后再做,或者多建一列,完成后删除原来的列!(如passwd)UP ...

  4. python-高阶函数和闭包

    高阶函数:把函数作为参数传入,这样的函数成为高阶函数. 高阶函数,higher-order function Abs()内置函数:绝对值 函数名是什么:指向函数的变量 传入函数 一个函数的参数是否可以 ...

  5. centos7下使用yum安装mysql数据库

    CentOS7的yum源中默认是没有mysql的.为了解决这个问题,我们要先下载mysql的repo源. 1.下载并安装MySQL官方的 Yum Repository wget -i -c http: ...

  6. HTML中table的td宽度无法固定问题

    设置了 width="10%" 依然会被内容撑大, 加了 style="word-break:break-all;" 属性就好了.效果是内容自动回车. 此属性不 ...

  7. Codeforces Round #361 (Div. 2) E. Mike and Geometry Problem 离散化+逆元

    E. Mike and Geometry Problem time limit per test 3 seconds memory limit per test 256 megabytes input ...

  8. log4j和logback

    Log4j和logback Log4j简介 Log4j(log for java) 1.是Apache的一个开源项目: 2.是使用Java语言编写的一个日志框架: 3.用于记录程序中的日志信息: 4. ...

  9. PHP会话控制之如何正确设置session_name

    定义: string session_name([string $name]) 说明: 在php.ini中配置为:session.name = PHPSESSID 在请求开始的时候,会话名称会被重置并 ...

  10. 在线前端开发平台 Plunker

    Plunker 网站 : http://plnkr.co/ Plunker 是一个用来创建.协作和分享 Web 开发思路的在线社区.编辑界面如下图所示: 特点: 基于 Node.js 环境运行 实时的 ...