create-element.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /* @flow */
  2. import VNode, { emptyVNode } from './vnode'
  3. import config from '../config'
  4. import { createComponent } from './create-component'
  5. import { normalizeChildren } from './helpers'
  6. import { warn, resolveAsset } from '../util/index'
  7. // wrapper function for providing a more flexible interface
  8. // without getting yelled at by flow
  9. export function createElement (
  10. tag: any,
  11. data: any,
  12. children: any
  13. ): VNode | Array<VNode> | void {
  14. if (data && (Array.isArray(data) || typeof data !== 'object')) {
  15. children = data
  16. data = undefined
  17. }
  18. // make sure to use real instance instead of proxy as context
  19. return _createElement(this._self, tag, data, children)
  20. }
  21. function _createElement (
  22. context: Component,
  23. tag?: string | Class<Component> | Function | Object,
  24. data?: VNodeData,
  25. children?: VNodeChildren | void
  26. ): VNode | Array<VNode> | void {
  27. if (data && data.__ob__) {
  28. process.env.NODE_ENV !== 'production' && warn(
  29. `Avoid using observed data object as vnode data: ${JSON.stringify(data)}\n` +
  30. 'Always create fresh vnode data objects in each render!',
  31. context
  32. )
  33. return
  34. }
  35. if (!tag) {
  36. // in case of component :is set to falsy value
  37. return emptyVNode()
  38. }
  39. if (typeof tag === 'string') {
  40. let Ctor
  41. const ns = config.getTagNamespace(tag)
  42. if (config.isReservedTag(tag)) {
  43. // platform built-in elements
  44. return new VNode(
  45. tag, data, normalizeChildren(children, ns),
  46. undefined, undefined, ns, context
  47. )
  48. } else if ((Ctor = resolveAsset(context.$options, 'components', tag))) {
  49. // component
  50. return createComponent(Ctor, data, context, children, tag)
  51. } else {
  52. // unknown or unlisted namespaced elements
  53. // check at runtime because it may get assigned a namespace when its
  54. // parent normalizes children
  55. return new VNode(
  56. tag, data, normalizeChildren(children, ns),
  57. undefined, undefined, ns, context
  58. )
  59. }
  60. } else {
  61. // direct component options / constructor
  62. return createComponent(tag, data, context, children)
  63. }
  64. }