lifecycle.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. var _ = require('../util')
  2. var compile = require('../compile/compile')
  3. /**
  4. * Set instance target element and kick off the compilation
  5. * process. The passed in `el` can be a selector string, an
  6. * existing Element, or a DocumentFragment (for block
  7. * instances).
  8. *
  9. * @param {Element|DocumentFragment|string} el
  10. * @public
  11. */
  12. exports.$mount = function (el) {
  13. if (this._isCompiled) {
  14. _.warn('$mount() should be called only once.')
  15. return
  16. }
  17. if (!el) {
  18. el = document.createElement('div')
  19. } else if (typeof el === 'string') {
  20. var selector = el
  21. el = document.querySelector(el)
  22. if (!el) {
  23. _.warn('Cannot find element: ' + selector)
  24. return
  25. }
  26. }
  27. this._compile(el)
  28. this._isCompiled = true
  29. this._callHook('compiled')
  30. if (_.inDoc(this.$el)) {
  31. this._callHook('attached')
  32. this._initDOMHooks()
  33. ready.call(this)
  34. } else {
  35. this._initDOMHooks()
  36. this.$once('hook:attached', ready)
  37. }
  38. return this
  39. }
  40. /**
  41. * Mark an instance as ready.
  42. */
  43. function ready () {
  44. this._isAttached = true
  45. this._isReady = true
  46. this._callHook('ready')
  47. }
  48. /**
  49. * Teardown an instance, unobserves the data, unbind all the
  50. * directives, turn off all the event listeners, etc.
  51. *
  52. * @param {Boolean} remove - whether to remove the DOM node.
  53. * @public
  54. */
  55. exports.$destroy = function (remove) {
  56. if (this._isDestroyed) {
  57. return
  58. }
  59. this._callHook('beforeDestroy')
  60. this._isBeingDestroyed = true
  61. var i
  62. // remove self from parent. only necessary
  63. // if parent is not being destroyed as well.
  64. var parent = this.$parent
  65. if (parent && !parent._isBeingDestroyed) {
  66. i = parent._children.indexOf(this)
  67. parent._children.splice(i, 1)
  68. }
  69. // destroy all children.
  70. if (this._children) {
  71. i = this._children.length
  72. while (i--) {
  73. this._children[i].$destroy()
  74. }
  75. }
  76. // teardown all directives. this also tearsdown all
  77. // directive-owned watchers.
  78. i = this._directives.length
  79. while (i--) {
  80. this._directives[i]._teardown()
  81. }
  82. // teardown all user watchers.
  83. for (i in this._userWatchers) {
  84. this._userWatchers[i].teardown()
  85. }
  86. // remove reference to self on $el
  87. if (this.$el) {
  88. this.$el.__vue__ = null
  89. }
  90. // remove DOM element
  91. var self = this
  92. if (remove && this.$el) {
  93. this.$remove(function () {
  94. cleanup(self)
  95. })
  96. } else {
  97. cleanup(self)
  98. }
  99. }
  100. /**
  101. * Clean up to ensure garbage collection.
  102. * This is called after the leave transition if there
  103. * is any.
  104. *
  105. * @param {Vue} vm
  106. */
  107. function cleanup (vm) {
  108. // remove reference from data ob
  109. vm._data.__ob__.removeVm(vm)
  110. vm._data =
  111. vm._watchers =
  112. vm._userWatchers =
  113. vm._watcherList =
  114. vm.$el =
  115. vm.$parent =
  116. vm.$root =
  117. vm._children =
  118. vm._bindings =
  119. vm._directives = null
  120. // call the last hook...
  121. vm._isDestroyed = true
  122. vm._callHook('destroyed')
  123. // turn off all instance listeners.
  124. vm.$off()
  125. }
  126. /**
  127. * Partially compile a piece of DOM and return a
  128. * decompile function.
  129. *
  130. * @param {Element|DocumentFragment} el
  131. * @return {Function}
  132. */
  133. exports.$compile = function (el) {
  134. return compile(el, this.$options, true)(this, el)
  135. }