PHP Classes

File: public/js/lib/vue/src/directives/internal/component.js

Recommend this page to a friend!
  Classes of Sergey Beskorovayniy   Silex MVC Blog   public/js/lib/vue/src/directives/internal/component.js   Download  
File: public/js/lib/vue/src/directives/internal/component.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Silex MVC Blog
MVC based blog using on the Silex micro-framework
Author: By
Last change:
Date: 8 years ago
Size: 10,000 bytes
 

Contents

Class file image Download
import { cloneNode } from '../../parsers/template' import { COMPONENT } from '../priorities' import { extractContent, createAnchor, replace, hyphenate, warn, cancellable, extend } from '../../util/index' export default { priority: COMPONENT, params: [ 'keep-alive', 'transition-mode', 'inline-template' ], /** * Setup. Two possible usages: * * - static: * <comp> or <div v-component="comp"> * * - dynamic: * <component :is="view"> */ bind () { if (!this.el.__vue__) { // keep-alive cache this.keepAlive = this.params.keepAlive if (this.keepAlive) { this.cache = {} } // check inline-template if (this.params.inlineTemplate) { // extract inline template as a DocumentFragment this.inlineTemplate = extractContent(this.el, true) } // component resolution related state this.pendingComponentCb = this.Component = null // transition related state this.pendingRemovals = 0 this.pendingRemovalCb = null // create a ref anchor this.anchor = createAnchor('v-component') replace(this.el, this.anchor) // remove is attribute. // this is removed during compilation, but because compilation is // cached, when the component is used elsewhere this attribute // will remain at link time. this.el.removeAttribute('is') this.el.removeAttribute(':is') // remove ref, same as above if (this.descriptor.ref) { this.el.removeAttribute('v-ref:' + hyphenate(this.descriptor.ref)) } // if static, build right now. if (this.literal) { this.setComponent(this.expression) } } else { process.env.NODE_ENV !== 'production' && warn( 'cannot mount component "' + this.expression + '" ' + 'on already mounted element: ' + this.el ) } }, /** * Public update, called by the watcher in the dynamic * literal scenario, e.g. <component :is="view"> */ update (value) { if (!this.literal) { this.setComponent(value) } }, /** * Switch dynamic components. May resolve the component * asynchronously, and perform transition based on * specified transition mode. Accepts a few additional * arguments specifically for vue-router. * * The callback is called when the full transition is * finished. * * @param {String} value * @param {Function} [cb] */ setComponent (value, cb) { this.invalidatePending() if (!value) { // just remove current this.unbuild(true) this.remove(this.childVM, cb) this.childVM = null } else { var self = this this.resolveComponent(value, function () { self.mountComponent(cb) }) } }, /** * Resolve the component constructor to use when creating * the child vm. * * @param {String|Function} value * @param {Function} cb */ resolveComponent (value, cb) { var self = this this.pendingComponentCb = cancellable(function (Component) { self.ComponentName = Component.options.name || (typeof value === 'string' ? value : null) self.Component = Component cb() }) this.vm._resolveComponent(value, this.pendingComponentCb) }, /** * Create a new instance using the current constructor and * replace the existing instance. This method doesn't care * whether the new component and the old one are actually * the same. * * @param {Function} [cb] */ mountComponent (cb) { // actual mount this.unbuild(true) var self = this var activateHooks = this.Component.options.activate var cached = this.getCached() var newComponent = this.build() if (activateHooks && !cached) { this.waitingFor = newComponent callActivateHooks(activateHooks, newComponent, function () { if (self.waitingFor !== newComponent) { return } self.waitingFor = null self.transition(newComponent, cb) }) } else { // update ref for kept-alive component if (cached) { newComponent._updateRef() } this.transition(newComponent, cb) } }, /** * When the component changes or unbinds before an async * constructor is resolved, we need to invalidate its * pending callback. */ invalidatePending () { if (this.pendingComponentCb) { this.pendingComponentCb.cancel() this.pendingComponentCb = null } }, /** * Instantiate/insert a new child vm. * If keep alive and has cached instance, insert that * instance; otherwise build a new one and cache it. * * @param {Object} [extraOptions] * @return {Vue} - the created instance */ build (extraOptions) { var cached = this.getCached() if (cached) { return cached } if (this.Component) { // default options var options = { name: this.ComponentName, el: cloneNode(this.el), template: this.inlineTemplate, // make sure to add the child with correct parent // if this is a transcluded component, its parent // should be the transclusion host. parent: this._host || this.vm, // if no inline-template, then the compiled // linker can be cached for better performance. _linkerCachable: !this.inlineTemplate, _ref: this.descriptor.ref, _asComponent: true, _isRouterView: this._isRouterView, // if this is a transcluded component, context // will be the common parent vm of this instance // and its host. _context: this.vm, // if this is inside an inline v-for, the scope // will be the intermediate scope created for this // repeat fragment. this is used for linking props // and container directives. _scope: this._scope, // pass in the owner fragment of this component. // this is necessary so that the fragment can keep // track of its contained components in order to // call attach/detach hooks for them. _frag: this._frag } // extra options // in 1.0.0 this is used by vue-router only /* istanbul ignore if */ if (extraOptions) { extend(options, extraOptions) } var child = new this.Component(options) if (this.keepAlive) { this.cache[this.Component.cid] = child } /* istanbul ignore if */ if (process.env.NODE_ENV !== 'production' && this.el.hasAttribute('transition') && child._isFragment) { warn( 'Transitions will not work on a fragment instance. ' + 'Template: ' + child.$options.template, child ) } return child } }, /** * Try to get a cached instance of the current component. * * @return {Vue|undefined} */ getCached () { return this.keepAlive && this.cache[this.Component.cid] }, /** * Teardown the current child, but defers cleanup so * that we can separate the destroy and removal steps. * * @param {Boolean} defer */ unbuild (defer) { if (this.waitingFor) { if (!this.keepAlive) { this.waitingFor.$destroy() } this.waitingFor = null } var child = this.childVM if (!child || this.keepAlive) { if (child) { // remove ref child._inactive = true child._updateRef(true) } return } // the sole purpose of `deferCleanup` is so that we can // "deactivate" the vm right now and perform DOM removal // later. child.$destroy(false, defer) }, /** * Remove current destroyed child and manually do * the cleanup after removal. * * @param {Function} cb */ remove (child, cb) { var keepAlive = this.keepAlive if (child) { // we may have a component switch when a previous // component is still being transitioned out. // we want to trigger only one lastest insertion cb // when the existing transition finishes. (#1119) this.pendingRemovals++ this.pendingRemovalCb = cb var self = this child.$remove(function () { self.pendingRemovals-- if (!keepAlive) child._cleanup() if (!self.pendingRemovals && self.pendingRemovalCb) { self.pendingRemovalCb() self.pendingRemovalCb = null } }) } else if (cb) { cb() } }, /** * Actually swap the components, depending on the * transition mode. Defaults to simultaneous. * * @param {Vue} target * @param {Function} [cb] */ transition (target, cb) { var self = this var current = this.childVM // for devtool inspection if (current) current._inactive = true target._inactive = false this.childVM = target switch (self.params.transitionMode) { case 'in-out': target.$before(self.anchor, function () { self.remove(current, cb) }) break case 'out-in': self.remove(current, function () { target.$before(self.anchor, cb) }) break default: self.remove(current) target.$before(self.anchor, cb) } }, /** * Unbind. */ unbind () { this.invalidatePending() // Do not defer cleanup when unbinding this.unbuild() // destroy all keep-alive cached instances if (this.cache) { for (var key in this.cache) { this.cache[key].$destroy() } this.cache = null } } } /** * Call activate hooks in order (asynchronous) * * @param {Array} hooks * @param {Vue} vm * @param {Function} cb */ function callActivateHooks (hooks, vm, cb) { var total = hooks.length var called = 0 hooks[0].call(vm, next) function next () { if (++called >= total) { cb() } else { hooks[called].call(vm, next) } } }