UNPKG

vue-loadable

Version:

Improves your loading state flow by providing methods and helpers to manage it.

165 lines (148 loc) 5.01 kB
/*! * vue-loadable v0.2.0 * (c) Vitor Cavalcanti <vitorluizc@outlook.com> (https://vitorluizc.github.io) * Released under the MIT License. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue')) : typeof define === 'function' && define.amd ? define(['exports', 'vue'], factory) : (global = global || self, factory(global.VueLoadable = {}, global.Vue)); }(this, function (exports, Vue) { 'use strict'; Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : 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; Object.defineProperty(exports, '__esModule', { value: true }); }));