aboutsummaryrefslogtreecommitdiff
path: root/node_modules/vue/src/core/vdom/create-functional-component.js
diff options
context:
space:
mode:
authorruki <waruqi@gmail.com>2018-11-08 00:38:48 +0800
committerruki <waruqi@gmail.com>2018-11-07 21:53:09 +0800
commit26105034da4fcce7ac883c899d781f016559310d (patch)
treec459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/vue/src/core/vdom/create-functional-component.js
parent2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff)
downloadxmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz
xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip
switch to vuepress
Diffstat (limited to 'node_modules/vue/src/core/vdom/create-functional-component.js')
-rw-r--r--node_modules/vue/src/core/vdom/create-functional-component.js136
1 files changed, 136 insertions, 0 deletions
diff --git a/node_modules/vue/src/core/vdom/create-functional-component.js b/node_modules/vue/src/core/vdom/create-functional-component.js
new file mode 100644
index 00000000..efed801d
--- /dev/null
+++ b/node_modules/vue/src/core/vdom/create-functional-component.js
@@ -0,0 +1,136 @@
+/* @flow */
+
+import VNode, { cloneVNode } from './vnode'
+import { createElement } from './create-element'
+import { resolveInject } from '../instance/inject'
+import { normalizeChildren } from '../vdom/helpers/normalize-children'
+import { resolveSlots } from '../instance/render-helpers/resolve-slots'
+import { installRenderHelpers } from '../instance/render-helpers/index'
+
+import {
+ isDef,
+ isTrue,
+ hasOwn,
+ camelize,
+ emptyObject,
+ validateProp
+} from '../util/index'
+
+export function FunctionalRenderContext (
+ data: VNodeData,
+ props: Object,
+ children: ?Array<VNode>,
+ parent: Component,
+ Ctor: Class<Component>
+) {
+ const options = Ctor.options
+ // ensure the createElement function in functional components
+ // gets a unique context - this is necessary for correct named slot check
+ let contextVm
+ if (hasOwn(parent, '_uid')) {
+ contextVm = Object.create(parent)
+ // $flow-disable-line
+ contextVm._original = parent
+ } else {
+ // the context vm passed in is a functional context as well.
+ // in this case we want to make sure we are able to get a hold to the
+ // real context instance.
+ contextVm = parent
+ // $flow-disable-line
+ parent = parent._original
+ }
+ const isCompiled = isTrue(options._compiled)
+ const needNormalization = !isCompiled
+
+ this.data = data
+ this.props = props
+ this.children = children
+ this.parent = parent
+ this.listeners = data.on || emptyObject
+ this.injections = resolveInject(options.inject, parent)
+ this.slots = () => resolveSlots(children, parent)
+
+ // support for compiled functional template
+ if (isCompiled) {
+ // exposing $options for renderStatic()
+ this.$options = options
+ // pre-resolve slots for renderSlot()
+ this.$slots = this.slots()
+ this.$scopedSlots = data.scopedSlots || emptyObject
+ }
+
+ if (options._scopeId) {
+ this._c = (a, b, c, d) => {
+ const vnode = createElement(contextVm, a, b, c, d, needNormalization)
+ if (vnode && !Array.isArray(vnode)) {
+ vnode.fnScopeId = options._scopeId
+ vnode.fnContext = parent
+ }
+ return vnode
+ }
+ } else {
+ this._c = (a, b, c, d) => createElement(contextVm, a, b, c, d, needNormalization)
+ }
+}
+
+installRenderHelpers(FunctionalRenderContext.prototype)
+
+export function createFunctionalComponent (
+ Ctor: Class<Component>,
+ propsData: ?Object,
+ data: VNodeData,
+ contextVm: Component,
+ children: ?Array<VNode>
+): VNode | Array<VNode> | void {
+ const options = Ctor.options
+ const props = {}
+ const propOptions = options.props
+ if (isDef(propOptions)) {
+ for (const key in propOptions) {
+ props[key] = validateProp(key, propOptions, propsData || emptyObject)
+ }
+ } else {
+ if (isDef(data.attrs)) mergeProps(props, data.attrs)
+ if (isDef(data.props)) mergeProps(props, data.props)
+ }
+
+ const renderContext = new FunctionalRenderContext(
+ data,
+ props,
+ children,
+ contextVm,
+ Ctor
+ )
+
+ const vnode = options.render.call(null, renderContext._c, renderContext)
+
+ if (vnode instanceof VNode) {
+ return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options)
+ } else if (Array.isArray(vnode)) {
+ const vnodes = normalizeChildren(vnode) || []
+ const res = new Array(vnodes.length)
+ for (let i = 0; i < vnodes.length; i++) {
+ res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options)
+ }
+ return res
+ }
+}
+
+function cloneAndMarkFunctionalResult (vnode, data, contextVm, options) {
+ // #7817 clone node before setting fnContext, otherwise if the node is reused
+ // (e.g. it was from a cached normal slot) the fnContext causes named slots
+ // that should not be matched to match.
+ const clone = cloneVNode(vnode)
+ clone.fnContext = contextVm
+ clone.fnOptions = options
+ if (data.slot) {
+ (clone.data || (clone.data = {})).slot = data.slot
+ }
+ return clone
+}
+
+function mergeProps (to, from) {
+ for (const key in from) {
+ to[camelize(key)] = from[key]
+ }
+}