UNPKG

bootstrap-vue

Version:

With more than 85 components, over 45 available plugins, several directives, and 1000+ icons, BootstrapVue provides one of the most comprehensive implementations of the Bootstrap v4 component and grid system available for Vue.js v2.6, complete with extens

131 lines (116 loc) 4.11 kB
import { extend } from '../vue'; import { arrayIncludes } from '../utils/array'; import { keys } from '../utils/object'; import { getEventRoot } from '../utils/get-event-root'; // --- Constants --- var PROP = '$_rootListeners'; // --- Mixin --- // @vue/component export var listenOnRootMixin = extend({ computed: { bvEventRoot: function bvEventRoot() { return getEventRoot(this); } }, created: function created() { // Define non-reactive property // Object of arrays, keyed by event name, // where value is an array of callbacks this[PROP] = {}; }, beforeDestroy: function beforeDestroy() { var _this = this; // Unregister all registered listeners keys(this[PROP] || {}).forEach(function (event) { _this[PROP][event].forEach(function (callback) { _this.listenOffRoot(event, callback); }); }); this[PROP] = null; }, methods: { registerRootListener: function registerRootListener(event, callback) { if (this[PROP]) { this[PROP][event] = this[PROP][event] || []; if (!arrayIncludes(this[PROP][event], callback)) { this[PROP][event].push(callback); } } }, unregisterRootListener: function unregisterRootListener(event, callback) { if (this[PROP] && this[PROP][event]) { this[PROP][event] = this[PROP][event].filter(function (cb) { return cb !== callback; }); } }, /** * Safely register event listeners on the root Vue node * While Vue automatically removes listeners for individual components, * when a component registers a listener on `$root` and is destroyed, * this orphans a callback because the node is gone, but the `$root` * does not clear the callback * * When registering a `$root` listener, it also registers the listener * to be removed in the component's `beforeDestroy()` hook * * @param {string} event * @param {function} callback */ listenOnRoot: function listenOnRoot(event, callback) { if (this.bvEventRoot) { this.bvEventRoot.$on(event, callback); this.registerRootListener(event, callback); } }, /** * Safely register a `$once()` event listener on the root Vue node * While Vue automatically removes listeners for individual components, * when a component registers a listener on `$root` and is destroyed, * this orphans a callback because the node is gone, but the `$root` * does not clear the callback * * When registering a `$root` listener, it also registers the listener * to be removed in the component's `beforeDestroy()` hook * * @param {string} event * @param {function} callback */ listenOnRootOnce: function listenOnRootOnce(event, callback) { var _this2 = this; if (this.bvEventRoot) { var _callback = function _callback() { _this2.unregisterRootListener(_callback); // eslint-disable-next-line node/no-callback-literal callback.apply(void 0, arguments); }; this.bvEventRoot.$once(event, _callback); this.registerRootListener(event, _callback); } }, /** * Safely unregister event listeners from the root Vue node * * @param {string} event * @param {function} callback */ listenOffRoot: function listenOffRoot(event, callback) { this.unregisterRootListener(event, callback); if (this.bvEventRoot) { this.bvEventRoot.$off(event, callback); } }, /** * Convenience method for calling `vm.$emit()` on `$root` * * @param {string} event * @param {*} args */ emitOnRoot: function emitOnRoot(event) { if (this.bvEventRoot) { var _this$bvEventRoot; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } (_this$bvEventRoot = this.bvEventRoot).$emit.apply(_this$bvEventRoot, [event].concat(args)); } } } });