var _ = require('../util') var compile = require('../compile/compile') /** * Set instance target element and kick off the compilation * process. The passed in `el` can be a selector string, an * existing Element, or a DocumentFragment (for block * instances). * * @param {Element|DocumentFragment|string} el * @public */ exports.$mount = function (el) { if (this._isCompiled) { _.warn('$mount() should be called only once.') return } if (!el) { el = document.createElement('div') } else if (typeof el === 'string') { var selector = el el = document.querySelector(el) if (!el) { _.warn('Cannot find element: ' + selector) return } } this._compile(el) this._isCompiled = true this._callHook('compiled') if (_.inDoc(this.$el)) { this._callHook('attached') this._initDOMHooks() ready.call(this) } else { this._initDOMHooks() this.$once('hook:attached', ready) } return this } /** * Mark an instance as ready. */ function ready () { this._isAttached = true this._isReady = true this._callHook('ready') } /** * Teardown an instance, unobserves the data, unbind all the * directives, turn off all the event listeners, etc. * * @param {Boolean} remove - whether to remove the DOM node. * @public */ exports.$destroy = function (remove) { if (this._isBeingDestroyed) { return } this._callHook('beforeDestroy') this._isBeingDestroyed = true var i // remove self from parent. only necessary // if parent is not being destroyed as well. var parent = this.$parent if (parent && !parent._isBeingDestroyed) { i = parent._children.indexOf(this) parent._children.splice(i, 1) } // destroy all children. if (this._children) { i = this._children.length while (i--) { this._children[i].$destroy() } } // teardown all directives. this also tearsdown all // directive-owned watchers. i = this._directives.length while (i--) { this._directives[i]._teardown() } // teardown all user watchers. for (i in this._userWatchers) { this._userWatchers[i].teardown() } // remove reference to self on $el if (this.$el) { this.$el.__vue__ = null } // remove DOM element var self = this if (remove && this.$el) { this.$remove(function () { cleanup(self) }) } else { cleanup(self) } } /** * Clean up to ensure garbage collection. * This is called after the leave transition if there * is any. * * @param {Vue} vm */ function cleanup (vm) { // remove reference from data ob vm._data.__ob__.removeVm(vm) vm._data = vm._watchers = vm._userWatchers = vm._watcherList = vm.$el = vm.$parent = vm.$root = vm._children = vm._bindings = vm._directives = null // call the last hook... vm._isDestroyed = true vm._callHook('destroyed') // turn off all instance listeners. vm.$off() } /** * Partially compile a piece of DOM and return a * decompile function. * * @param {Element|DocumentFragment} el * @return {Function} */ exports.$compile = function (el) { return compile(el, this.$options, true)(this, el) }