vue-loadable
Version:
Improves your loading state flow by providing methods and helpers to manage it.
161 lines (144 loc) • 4.5 kB
JavaScript
/*!
* vue-loadable v0.2.0
* (c) Vitor Cavalcanti <vitorluizc@outlook.com> (https://vitorluizc.github.io)
* Released under the MIT License.
*/
;
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var Vue = _interopDefault(require('vue'));
/**
* A mixin which adds loading states and helpers to Vue components.
* @example ```js
* Vue.component('SignUpForm', {
* mixins: [ LoadableMixin ],
* ...,
* mounted () {
* if (this.$isLoadingAny())
* console.log('Loading...');
* }
* })```
*/
var LoadableMixin = Vue.extend({
data: function data() {
return {
LOADING_STATES: Object.create(null)
};
},
methods: {
$isLoading: function $isLoading() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unknown';
var value = this.LOADING_STATES[state];
return !!value && value > 0;
},
$isLoadingAny: function $isLoadingAny() {
return Object.keys(this.LOADING_STATES).some(this.$isLoading);
},
$setLoading: function $setLoading() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unknown';
var value = this.LOADING_STATES[state];
this.$set(this.LOADING_STATES, state, value ? value + 1 : 1);
},
$unsetLoading: function $unsetLoading() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unknown';
var value = this.LOADING_STATES[state];
this.$set(this.LOADING_STATES, state, value ? value - 1 : 0);
}
}
});
/**
* Call function and execute its hooks. Executes `onDone` when its done and
* `onError` when it throws an error.
* @param call
* @param onDone
* @param onError
*/
var callWithHooks = function callWithHooks(call, onDone) {
var onError = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : onDone;
var handleError = function handleError(error) {
onError();
return Promise.reject(error);
};
try {
return Promise.resolve(call()).then(function (value) {
onDone();
return Promise.resolve(value);
})["catch"](handleError);
} catch (error) {
return handleError(error);
}
};
/**
* Decorate a method to causes loading states changes during its execution. It
* sets state as loading when function is init and unsets on throws an error or
* resolve/return.
* @example
* Vue.component('SignInForm', {
* methods: {
* signIn: loadable(async function ({ email, password }) {
* // ...
* }, 'signIn')
* }
* });
* @param method - A method, commonly async, which causes loading state changes.
* @param [state] - Loading state name. It's "unknown" if not defined.
*/
var loadable = function loadable(method) {
var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'unknown';
return function () {
var _this = this,
_arguments = arguments;
this.$setLoading(state);
return callWithHooks(function () {
return method.apply(_this, _arguments);
}, function () {
return _this.$unsetLoading(state);
});
};
};
/**
* Maps an object, whose keys are `string` and the values are methods, to
* loadable methods that triggers loading states. It uses property's keys as
* loading state names.
* @example
* Vue.component('SignInForm', {
* ...,
* methods: {
* onClick() {
* if (this.$isLoading('signIn') || this.$isLoading('signUp'))
* return;
* // ...
* },
* ...mapLoadableMethods(
* mapActions('authentication', [
* 'signIn',
* 'signUp'
* ])
* )
* }
* });
*/
var mapLoadableMethods = function mapLoadableMethods(methods) {
var names = Object.keys(methods);
return names.reduce(function (loadableMethods, name) {
loadableMethods[name] = loadable(methods[name], name);
return loadableMethods;
}, Object.create(null));
};
/**
* Installs LoadableMixin globally.
* @example ```js
* Vue.use(install)```
* @param Vue - The Vue constructor.
*/
function install(Vue) {
Vue.mixin(LoadableMixin);
}
var vueLoadable = {
install: install
};
exports.LoadableMixin = LoadableMixin;
exports.default = vueLoadable;
exports.install = install;
exports.loadable = loadable;
exports.mapLoadableMethods = mapLoadableMethods;