vue-navigation-progress-plugin
Version:
161 lines (153 loc) • 4.86 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.vueNavigationProgressPlugin = factory());
}(this, (function () { 'use strict';
var routerProgress = {
render: function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"router-progress",style:(_vm.style)})},
staticRenderFns: [],
name: "router-progress",
computed: {
style: function style () {
return {
transform: ("translate3d(" + (this.percent - 100) + "%, 0, 0)"),
backgroundColor: this.canSuccess ? this.color : this.failedColor,
opacity: this.show ? 1 : 0
};
}
},
created: function created () {
!this.$root.$progress && (this.$root.$progress = this);
},
props: {
duration: {
type: Number,
default: 3000
},
color: {
type: String,
default: "#77b6ff"
},
failedColor: {
type: String,
default: "red"
}
},
data: function data () {
return {
percent: 0,
show: false,
canSuccess: true
};
},
methods: {
start: function start () {
var this$1 = this;
this.show = true;
this.canSuccess = true;
if (this._timer) {
clearInterval(this._timer);
this.percent = 0;
}
this._cut = 10000 / Math.floor(this.duration);
this._timer = setInterval(function () {
this$1.increase(this$1._cut * Math.random());
if (this$1.percent > 90) {
this$1.pause();
}
}, 100);
},
set: function set (num) {
this.show = true;
this.canSuccess = true;
this.percent = Math.floor(num);
},
get: function get () {
return Math.floor(this.percent);
},
increase: function increase (num) {
this.percent = this.percent + Math.floor(num);
},
decrease: function decrease (num) {
this.percent = this.percent - Math.floor(num);
},
finish: function finish () {
this.percent = 100;
this.hide();
},
pause: function pause () {
clearInterval(this._timer);
},
hide: function hide () {
var this$1 = this;
clearInterval(this._timer);
this._timer = null;
setTimeout(function () {
this$1.show = false;
this$1.$nextTick(function () {
setTimeout(function () {
this$1.percent = 0;
}, 200);
});
}, 500);
},
fail: function fail () {
this.canSuccess = false;
}
}
};
// reference self https://nuxtjs.org
var flatMapComponents = function (route, fn) {
return Array.prototype.concat.apply([], route.matched.map(function (m, index) {
return Object.keys(m.components).map(function (key) {
return fn(m.components[key], m, key, index);
});
}));
};
var loadAsyncComponents = function (to, from, next, Vue, router) {
var $progress = router.app && router.app.$root.$progress;
var resolveComponents = flatMapComponents(to, function (Component, match, key) {
if (typeof Component === "function" && !Component.options) {
return new Promise(function (resolve, reject) {
var _resolve = function (Component) {
if (!Component.options) {
Component = Vue.extend(Component); // fix issue #6
Component._Ctor = Component;
} else {
Component._Ctor = Component;
Component.extendOptions = Component.options;
}
match.components[key] = Component;
resolve(Component);
};
Component().then(_resolve).catch(reject);
});
}
return Component;
});
var fromPath = from.fullPath.split("#")[0];
var toPath = to.fullPath.split("#")[0];
if (!(fromPath === toPath)) {
$progress && $progress.start();
}
Promise.all(resolveComponents).then(function () {
$progress && $progress.finish();
next();
}, function () {
$progress && $progress.fail();
$progress && $progress.finish();
next(false);
});
};
var index = {
install: function install (Vue, router) {
var style = document.createElement("style");
style.type = "text/css";
style.textContent = ".router-progress{position:fixed;top:0;left:0;right:0;height:2px;width:100%;transition:transform .3s ease-out,opacity .3s ease-out;box-shadow:rgba(119,182,255,.7);z-index:9999}";
document.head.appendChild(style);
Vue.component(routerProgress.name, routerProgress);
router.beforeEach(function (to, from, next) { return loadAsyncComponents(to, from, next, Vue, router); });
}
};
return index;
})));