This commit is contained in:
梁灏 2017-09-19 14:26:46 +08:00
parent 300bd6623e
commit 297648f1e6
9 changed files with 180 additions and 33 deletions

View file

@ -181,6 +181,8 @@
</div>
<br>
切换显示状态<i-switch @on-change="spinShow = !spinShow"></i-switch>
<Button @click="show">show</Button>
<Button @click="hide">hide</Button>
</div>
</template>
<script>
@ -189,6 +191,29 @@
return {
spinShow: true
}
},
methods: {
show () {
this.$Spin.show({
render: (h) => {
return h('div', [
h('Icon', {
props: {
type: 'load-c',
size: 24
}
}),
h('div', 'Loading')
])
}
});
setTimeout(() => {
this.$Spin.hide();
}, 3000)
},
hide () {
this.$Spin.hide();
}
}
}
</script>

View file

@ -0,0 +1,34 @@
// used for Modal & $Spin
import { getScrollBarSize } from '../../utils/assist';
export default {
methods: {
checkScrollBar () {
let fullWindowWidth = window.innerWidth;
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
const documentElementRect = document.documentElement.getBoundingClientRect();
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
}
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth;
if (this.bodyIsOverflowing) {
this.scrollBarWidth = getScrollBarSize();
}
},
setScrollBar () {
if (this.bodyIsOverflowing && this.scrollBarWidth !== undefined) {
document.body.style.paddingRight = `${this.scrollBarWidth}px`;
}
},
resetScrollBar () {
document.body.style.paddingRight = '';
},
addScrollEffect () {
this.checkScrollBar();
this.setScrollBar();
document.body.style.overflow = 'hidden';
},
removeScrollEffect() {
document.body.style.overflow = '';
this.resetScrollBar();
}
}
};

View file

@ -30,15 +30,15 @@
import Icon from '../icon';
import iButton from '../button/button.vue';
import TransferDom from '../../directives/transfer-dom';
import { getScrollBarSize } from '../../utils/assist';
import Locale from '../../mixins/locale';
import Emitter from '../../mixins/emitter';
import ScrollbarMixins from './mixins-scrollbar';
const prefixCls = 'ivu-modal';
export default {
name: 'Modal',
mixins: [ Locale, Emitter ],
mixins: [ Locale, Emitter, ScrollbarMixins ],
components: { Icon, iButton },
directives: { TransferDom },
props: {
@ -186,34 +186,6 @@
}
}
},
checkScrollBar () {
let fullWindowWidth = window.innerWidth;
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
const documentElementRect = document.documentElement.getBoundingClientRect();
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
}
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth;
if (this.bodyIsOverflowing) {
this.scrollBarWidth = getScrollBarSize();
}
},
setScrollBar () {
if (this.bodyIsOverflowing && this.scrollBarWidth !== undefined) {
document.body.style.paddingRight = `${this.scrollBarWidth}px`;
}
},
resetScrollBar () {
document.body.style.paddingRight = '';
},
addScrollEffect () {
this.checkScrollBar();
this.setScrollBar();
document.body.style.overflow = 'hidden';
},
removeScrollEffect() {
document.body.style.overflow = '';
this.resetScrollBar();
},
animationFinish() {
this.$emit('on-hidden');
}

View file

@ -1,2 +1,33 @@
import Spin from './spin.vue';
import Spin from './spin.js';
let spinInstance;
function getSpinInstance (render = undefined) {
spinInstance = spinInstance || Spin.newInstance({
render: render
});
return spinInstance;
}
function loading (options) {
const render = ('render' in options) ? options.render : undefined;
let instance = getSpinInstance(render);
instance.show(options);
}
Spin.show = function (props = {}) {
return loading(props);
};
Spin.hide = function () {
if (!spinInstance) return false;
const instance = getSpinInstance();
instance.remove(() => {
spinInstance = null;
});
};
export default Spin;

View file

@ -0,0 +1,55 @@
import Vue from 'vue';
import Spin from './spin.vue';
Spin.newInstance = properties => {
const _props = properties || {};
const Instance = new Vue({
data: Object.assign({}, _props, {
}),
render (h) {
let vnode = '';
if (this.render) {
vnode = h(Spin, {
props: {
fix: true,
fullscreen: true
}
}, [this.render(h)]);
} else {
vnode = h(Spin, {
props: {
size: 'large',
fix: true,
fullscreen: true
}
});
}
return h('div', {
'class': 'ivu-spin-fullscreen'
}, [vnode]);
}
});
const component = Instance.$mount();
document.body.appendChild(component.$el);
const spin = Instance.$children[0];
return {
show () {
spin.visible = true;
},
remove (cb) {
spin.visible = false;
setTimeout(function() {
spin.$parent.$destroy();
document.body.removeChild(document.getElementsByClassName('ivu-spin-fullscreen')[0]);
cb();
}, 500);
},
component: spin
};
};
export default Spin;

View file

@ -1,6 +1,6 @@
<template>
<transition name="fade">
<div :class="classes">
<div :class="classes" v-if="fullscreenVisible">
<div :class="mainClasses">
<span :class="dotClasses"></span>
<div :class="textClasses"><slot></slot></div>
@ -10,11 +10,13 @@
</template>
<script>
import { oneOf } from '../../utils/assist';
import ScrollbarMixins from '../modal/mixins-scrollbar';
const prefixCls = 'ivu-spin';
export default {
name: 'Spin',
mixins: [ ScrollbarMixins ],
props: {
size: {
validator (value) {
@ -24,11 +26,17 @@
fix: {
type: Boolean,
default: false
},
fullscreen: {
type: Boolean,
default: false
}
},
data () {
return {
showText: false
showText: false,
// used for $Spin
visible: false
};
},
computed: {
@ -39,6 +47,7 @@
[`${prefixCls}-${this.size}`]: !!this.size,
[`${prefixCls}-fix`]: this.fix,
[`${prefixCls}-show-text`]: this.showText,
[`${prefixCls}-fullscreen`]: this.fullscreen
}
];
},
@ -50,6 +59,22 @@
},
textClasses () {
return `${prefixCls}-text`;
},
fullscreenVisible () {
if (this.fullscreen) {
return this.visible;
} else {
return true;
}
}
},
watch: {
visible (val) {
if (val) {
this.addScrollEffect();
} else {
this.removeScrollEffect();
}
}
},
mounted () {

View file

@ -139,6 +139,7 @@ const install = function (Vue, opts = {}) {
Vue.prototype.$Message = Message;
Vue.prototype.$Modal = Modal;
Vue.prototype.$Notice = Notice;
Vue.prototype.$Spin = Spin;
};
// auto install

View file

@ -33,6 +33,9 @@
.square(100%);
background-color: rgba(255,255,255,.9);
}
&-fullscreen{
z-index: @zindex-spin-fullscreen;
}
&-fix &-main {
position: absolute;

View file

@ -149,6 +149,7 @@
@zindex-tooltip : 1060;
@zindex-transfer : 1060;
@zindex-loading-bar : 2000;
@zindex-spin-fullscreen : 2010;
// Animation
@animation-time : .3s;