/* @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. Pentester中的XSS详解

    本次做的是Web For Pentester靶机里面的XSS题目,一共有9道题目. 关于靶机搭建参考这篇文章:渗透测试靶机的搭建 第1题(无过滤措施) 首先在后面输入xss: http://10.21 ...

  2. Python面试题之解读Socketserver & Tcpserver

    在解析socketserver是如工作之前,我们先看看socektserver类的继承关系图: 请求类继承关系: server类继承关系: 有了上面的继承关系图后,我们解析socketserver就轻 ...

  3. GET 对比 POST

    HTTP 方法:GET 对比 POST HTTP 消息 标签列表(字母排序) 两种最常用的 HTTP 方法是:GET 和 POST. 什么是 HTTP? 超文本传输协议(HTTP)的设计目的是保证客户 ...

  4. mybatis家族

    mybatis 优秀的持久层框架,它支持定制化SQL.存储过程以及高级映射. 备注:通过mapper实现数据库与实体类相互映射 MyBatis 避免了几乎所有的JDBC 代码和手动设置参数以及获取结果 ...

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

    20145318 <Java程序设计>第2周学习总结 教材学习内容总结 short,2字节:int,4字节:long,8字节:byte,1字节:float,4字节:double,8字节:c ...

  6. openwrt下如何只编译linux内核

    答:make target/linux/install V=s (此操作也会将最终镜像打包好,V=s会输出日志) 拓展 清空内核: make target/linux/clean V=s 解压内核: ...

  7. 设置iframe内表单target属性以兼容IE、Firefox【转载】

    设置iframe内表单target属性以兼容IE.Firefox[转载] 2011年11月19日 haibor       今天有客户反应,在一产品网站的资源下载页面,用户登录提交后页面无反应! 经测 ...

  8. Linux命令:chmod、chgrp、chown的区别

    chmod是更改文件的权限: chgrp只是更改文件的属组: chown是更改文件的属主与属组. 1.chmod:更改文件的权限 文件权限的设置方式有两种,分别是数字和标记. mode : 权限设定字 ...

  9. unix_timestamp() 和 from_unixtime()

    unix_timestamp() 将时间转换为时间戳.(date 类型数据转换成 timestamp 形式整数) select unix_timestamp('2016-03-23 11:10:10' ...

  10. Ice Cream Tower

    2017-08-18 21:53:38 writer:pprp 题意如下: Problem D. Ice Cream Tower Input file: Standard Input Output f ...