31e3b47d98e990c910fc1c08f8c3e26c40730b0bfd2851f4df5703f07508ea9938ad0f99ac6943d9bb692dc83c63824a0ce1df92ee9b612ec8acd2cd50cb16 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /* @flow */
  2. import config from 'core/config'
  3. import { warn, cached } from 'core/util/index'
  4. import { mark, measure } from 'core/util/perf'
  5. import Vue from './runtime/index'
  6. import { query } from './util/index'
  7. import { compileToFunctions } from './compiler/index'
  8. import { shouldDecodeNewlines, shouldDecodeNewlinesForHref } from './util/compat'
  9. const idToTemplate = cached(id => {
  10. const el = query(id)
  11. return el && el.innerHTML
  12. })
  13. const mount = Vue.prototype.$mount
  14. Vue.prototype.$mount = function (
  15. el?: string | Element,
  16. hydrating?: boolean
  17. ): Component {
  18. el = el && query(el)
  19. /* istanbul ignore if */
  20. if (el === document.body || el === document.documentElement) {
  21. process.env.NODE_ENV !== 'production' && warn(
  22. `Do not mount Vue to <html> or <body> - mount to normal elements instead.`
  23. )
  24. return this
  25. }
  26. const options = this.$options
  27. // resolve template/el and convert to render function
  28. if (!options.render) {
  29. let template = options.template
  30. if (template) {
  31. if (typeof template === 'string') {
  32. if (template.charAt(0) === '#') {
  33. template = idToTemplate(template)
  34. /* istanbul ignore if */
  35. if (process.env.NODE_ENV !== 'production' && !template) {
  36. warn(
  37. `Template element not found or is empty: ${options.template}`,
  38. this
  39. )
  40. }
  41. }
  42. } else if (template.nodeType) {
  43. template = template.innerHTML
  44. } else {
  45. if (process.env.NODE_ENV !== 'production') {
  46. warn('invalid template option:' + template, this)
  47. }
  48. return this
  49. }
  50. } else if (el) {
  51. template = getOuterHTML(el)
  52. }
  53. if (template) {
  54. /* istanbul ignore if */
  55. if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
  56. mark('compile')
  57. }
  58. const { render, staticRenderFns } = compileToFunctions(template, {
  59. outputSourceRange: process.env.NODE_ENV !== 'production',
  60. shouldDecodeNewlines,
  61. shouldDecodeNewlinesForHref,
  62. delimiters: options.delimiters,
  63. comments: options.comments
  64. }, this)
  65. options.render = render
  66. options.staticRenderFns = staticRenderFns
  67. /* istanbul ignore if */
  68. if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
  69. mark('compile end')
  70. measure(`vue ${this._name} compile`, 'compile', 'compile end')
  71. }
  72. }
  73. }
  74. return mount.call(this, el, hydrating)
  75. }
  76. /**
  77. * Get outerHTML of elements, taking care
  78. * of SVG elements in IE as well.
  79. */
  80. function getOuterHTML (el: Element): string {
  81. if (el.outerHTML) {
  82. return el.outerHTML
  83. } else {
  84. const container = document.createElement('div')
  85. container.appendChild(el.cloneNode(true))
  86. return container.innerHTML
  87. }
  88. }
  89. Vue.compile = compileToFunctions
  90. export default Vue