فهرست منبع

refactor create-component.js

Evan You 9 سال پیش
والد
کامیت
86a714cc47

+ 7 - 116
src/core/vdom/create-component.js

@@ -6,15 +6,16 @@ import { resolveConstructorOptions } from '../instance/init'
 import { resolveSlots } from '../instance/render-helpers/resolve-slots'
 
 import {
-  tip,
   warn,
   isObject,
-  hasOwn,
-  hyphenate,
-  validateProp,
-  formatComponentName
+  validateProp
 } from '../util/index'
 
+import {
+  resolveAsyncComponent,
+  extractPropsFromVNodeData
+} from './helpers/index'
+
 import {
   callHook,
   activeInstance,
@@ -134,7 +135,7 @@ export function createComponent (
   }
 
   // extract props
-  const propsData = extractProps(data, Ctor, tag)
+  const propsData = extractPropsFromVNodeData(data, Ctor, tag)
 
   // functional component
   if (Ctor.options.functional) {
@@ -227,116 +228,6 @@ export function createComponentInstanceForVnode (
   return new vnodeComponentOptions.Ctor(options)
 }
 
-function resolveAsyncComponent (
-  factory: Function,
-  baseCtor: Class<Component>,
-  cb: Function
-): Class<Component> | void {
-  if (factory.requested) {
-    // pool callbacks
-    factory.pendingCallbacks.push(cb)
-  } else {
-    factory.requested = true
-    const cbs = factory.pendingCallbacks = [cb]
-    let sync = true
-
-    const resolve = (res: Object | Class<Component>) => {
-      if (isObject(res)) {
-        res = baseCtor.extend(res)
-      }
-      // cache resolved
-      factory.resolved = res
-      // invoke callbacks only if this is not a synchronous resolve
-      // (async resolves are shimmed as synchronous during SSR)
-      if (!sync) {
-        for (let i = 0, l = cbs.length; i < l; i++) {
-          cbs[i](res)
-        }
-      }
-    }
-
-    const reject = reason => {
-      process.env.NODE_ENV !== 'production' && warn(
-        `Failed to resolve async component: ${String(factory)}` +
-        (reason ? `\nReason: ${reason}` : '')
-      )
-    }
-
-    const res = factory(resolve, reject)
-
-    // handle promise
-    if (res && typeof res.then === 'function' && !factory.resolved) {
-      res.then(resolve, reject)
-    }
-
-    sync = false
-    // return in case resolved synchronously
-    return factory.resolved
-  }
-}
-
-function extractProps (data: VNodeData, Ctor: Class<Component>, tag?: string): ?Object {
-  // we are only extracting raw values here.
-  // validation and default values are handled in the child
-  // component itself.
-  const propOptions = Ctor.options.props
-  if (!propOptions) {
-    return
-  }
-  const res = {}
-  const { attrs, props, domProps } = data
-  if (attrs || props || domProps) {
-    for (const key in propOptions) {
-      const altKey = hyphenate(key)
-      if (process.env.NODE_ENV !== 'production') {
-        const keyInLowerCase = key.toLowerCase()
-        if (
-          key !== keyInLowerCase &&
-          attrs && attrs.hasOwnProperty(keyInLowerCase)
-        ) {
-          tip(
-            `Prop "${keyInLowerCase}" is passed to component ` +
-            `${formatComponentName(tag || Ctor)}, but the declared prop name is` +
-            ` "${key}". ` +
-            `Note that HTML attributes are case-insensitive and camelCased ` +
-            `props need to use their kebab-case equivalents when using in-DOM ` +
-            `templates. You should probably use "${altKey}" instead of "${key}".`
-          )
-        }
-      }
-      checkProp(res, props, key, altKey, true) ||
-      checkProp(res, attrs, key, altKey) ||
-      checkProp(res, domProps, key, altKey)
-    }
-  }
-  return res
-}
-
-function checkProp (
-  res: Object,
-  hash: ?Object,
-  key: string,
-  altKey: string,
-  preserve?: boolean
-): boolean {
-  if (hash) {
-    if (hasOwn(hash, key)) {
-      res[key] = hash[key]
-      if (!preserve) {
-        delete hash[key]
-      }
-      return true
-    } else if (hasOwn(hash, altKey)) {
-      res[key] = hash[altKey]
-      if (!preserve) {
-        delete hash[altKey]
-      }
-      return true
-    }
-  }
-  return false
-}
-
 function mergeHooks (data: VNodeData) {
   if (!data.hook) {
     data.hook = {}

+ 12 - 3
src/core/vdom/create-element.js

@@ -1,10 +1,19 @@
 /* @flow */
 
-import VNode, { createEmptyVNode } from './vnode'
 import config from '../config'
+import VNode, { createEmptyVNode } from './vnode'
 import { createComponent } from './create-component'
-import { normalizeChildren, simpleNormalizeChildren } from './helpers/index'
-import { warn, resolveAsset, isPrimitive } from '../util/index'
+
+import {
+  warn,
+  resolveAsset,
+  isPrimitive
+} from '../util/index'
+
+import {
+  normalizeChildren,
+  simpleNormalizeChildren
+} from './helpers/index'
 
 const SIMPLE_NORMALIZE = 1
 const ALWAYS_NORMALIZE = 2

+ 74 - 0
src/core/vdom/helpers/extract-props.js

@@ -0,0 +1,74 @@
+/* @flow */
+
+import {
+  tip,
+  hasOwn,
+  hyphenate,
+  formatComponentName
+} from 'core/util/index'
+
+export function extractPropsFromVNodeData (
+  data: VNodeData,
+  Ctor: Class<Component>,
+  tag?: string
+): ?Object {
+  // we are only extracting raw values here.
+  // validation and default values are handled in the child
+  // component itself.
+  const propOptions = Ctor.options.props
+  if (!propOptions) {
+    return
+  }
+  const res = {}
+  const { attrs, props, domProps } = data
+  if (attrs || props || domProps) {
+    for (const key in propOptions) {
+      const altKey = hyphenate(key)
+      if (process.env.NODE_ENV !== 'production') {
+        const keyInLowerCase = key.toLowerCase()
+        if (
+          key !== keyInLowerCase &&
+          attrs && attrs.hasOwnProperty(keyInLowerCase)
+        ) {
+          tip(
+            `Prop "${keyInLowerCase}" is passed to component ` +
+            `${formatComponentName(tag || Ctor)}, but the declared prop name is` +
+            ` "${key}". ` +
+            `Note that HTML attributes are case-insensitive and camelCased ` +
+            `props need to use their kebab-case equivalents when using in-DOM ` +
+            `templates. You should probably use "${altKey}" instead of "${key}".`
+          )
+        }
+      }
+      checkProp(res, props, key, altKey, true) ||
+      checkProp(res, attrs, key, altKey) ||
+      checkProp(res, domProps, key, altKey)
+    }
+  }
+  return res
+}
+
+function checkProp (
+  res: Object,
+  hash: ?Object,
+  key: string,
+  altKey: string,
+  preserve?: boolean
+): boolean {
+  if (hash) {
+    if (hasOwn(hash, key)) {
+      res[key] = hash[key]
+      if (!preserve) {
+        delete hash[key]
+      }
+      return true
+    } else if (hasOwn(hash, altKey)) {
+      res[key] = hash[altKey]
+      if (!preserve) {
+        delete hash[altKey]
+      }
+      return true
+    }
+  }
+  return false
+}

+ 2 - 0
src/core/vdom/helpers/index.js

@@ -1,8 +1,10 @@
 /* @flow */
 
 export * from './merge-hook'
+export * from './extract-props'
 export * from './update-listeners'
 export * from './normalize-children'
+export * from './resolve-async-component'
 
 export function getFirstComponentChild (children: ?Array<VNode>): ?VNode {
   return children && children.filter((c: VNode) => c && c.componentOptions)[0]

+ 54 - 0
src/core/vdom/helpers/resolve-async-component.js

@@ -0,0 +1,54 @@
+/* @flow */
+
+import {
+  warn,
+  isObject
+} from 'core/util/index'
+
+export function resolveAsyncComponent (
+  factory: Function,
+  baseCtor: Class<Component>,
+  cb: Function
+): Class<Component> | void {
+  if (factory.requested) {
+    // pool callbacks
+    factory.pendingCallbacks.push(cb)
+  } else {
+    factory.requested = true
+    const cbs = factory.pendingCallbacks = [cb]
+    let sync = true
+
+    const resolve = (res: Object | Class<Component>) => {
+      if (isObject(res)) {
+        res = baseCtor.extend(res)
+      }
+      // cache resolved
+      factory.resolved = res
+      // invoke callbacks only if this is not a synchronous resolve
+      // (async resolves are shimmed as synchronous during SSR)
+      if (!sync) {
+        for (let i = 0, l = cbs.length; i < l; i++) {
+          cbs[i](res)
+        }
+      }
+    }
+
+    const reject = reason => {
+      process.env.NODE_ENV !== 'production' && warn(
+        `Failed to resolve async component: ${String(factory)}` +
+        (reason ? `\nReason: ${reason}` : '')
+      )
+    }
+
+    const res = factory(resolve, reject)
+
+    // handle promise
+    if (res && typeof res.then === 'function' && !factory.resolved) {
+      res.then(resolve, reject)
+    }
+
+    sync = false
+    // return in case resolved synchronously
+    return factory.resolved
+  }
+}