Commit 297648f1e634900ce4e22498f9c061f670c7321f

Authored by 梁灏
1 parent 300bd662

fixed #1063

examples/routers/spin.vue
... ... @@ -181,6 +181,8 @@
181 181 </div>
182 182 <br>
183 183 切换显示状态:<i-switch @on-change="spinShow = !spinShow"></i-switch>
  184 + <Button @click="show">show</Button>
  185 + <Button @click="hide">hide</Button>
184 186 </div>
185 187 </template>
186 188 <script>
... ... @@ -189,6 +191,29 @@
189 191 return {
190 192 spinShow: true
191 193 }
  194 + },
  195 + methods: {
  196 + show () {
  197 + this.$Spin.show({
  198 + render: (h) => {
  199 + return h('div', [
  200 + h('Icon', {
  201 + props: {
  202 + type: 'load-c',
  203 + size: 24
  204 + }
  205 + }),
  206 + h('div', 'Loading')
  207 + ])
  208 + }
  209 + });
  210 + setTimeout(() => {
  211 + this.$Spin.hide();
  212 + }, 3000)
  213 + },
  214 + hide () {
  215 + this.$Spin.hide();
  216 + }
192 217 }
193 218 }
194 219 </script>
... ...
src/components/modal/mixins-scrollbar.js 0 → 100644
  1 +// used for Modal & $Spin
  2 +import { getScrollBarSize } from '../../utils/assist';
  3 +export default {
  4 + methods: {
  5 + checkScrollBar () {
  6 + let fullWindowWidth = window.innerWidth;
  7 + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
  8 + const documentElementRect = document.documentElement.getBoundingClientRect();
  9 + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
  10 + }
  11 + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth;
  12 + if (this.bodyIsOverflowing) {
  13 + this.scrollBarWidth = getScrollBarSize();
  14 + }
  15 + },
  16 + setScrollBar () {
  17 + if (this.bodyIsOverflowing && this.scrollBarWidth !== undefined) {
  18 + document.body.style.paddingRight = `${this.scrollBarWidth}px`;
  19 + }
  20 + },
  21 + resetScrollBar () {
  22 + document.body.style.paddingRight = '';
  23 + },
  24 + addScrollEffect () {
  25 + this.checkScrollBar();
  26 + this.setScrollBar();
  27 + document.body.style.overflow = 'hidden';
  28 + },
  29 + removeScrollEffect() {
  30 + document.body.style.overflow = '';
  31 + this.resetScrollBar();
  32 + }
  33 + }
  34 +};
0 35 \ No newline at end of file
... ...
src/components/modal/modal.vue
... ... @@ -30,15 +30,15 @@
30 30 import Icon from '../icon';
31 31 import iButton from '../button/button.vue';
32 32 import TransferDom from '../../directives/transfer-dom';
33   - import { getScrollBarSize } from '../../utils/assist';
34 33 import Locale from '../../mixins/locale';
35 34 import Emitter from '../../mixins/emitter';
  35 + import ScrollbarMixins from './mixins-scrollbar';
36 36  
37 37 const prefixCls = 'ivu-modal';
38 38  
39 39 export default {
40 40 name: 'Modal',
41   - mixins: [ Locale, Emitter ],
  41 + mixins: [ Locale, Emitter, ScrollbarMixins ],
42 42 components: { Icon, iButton },
43 43 directives: { TransferDom },
44 44 props: {
... ... @@ -186,34 +186,6 @@
186 186 }
187 187 }
188 188 },
189   - checkScrollBar () {
190   - let fullWindowWidth = window.innerWidth;
191   - if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
192   - const documentElementRect = document.documentElement.getBoundingClientRect();
193   - fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
194   - }
195   - this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth;
196   - if (this.bodyIsOverflowing) {
197   - this.scrollBarWidth = getScrollBarSize();
198   - }
199   - },
200   - setScrollBar () {
201   - if (this.bodyIsOverflowing && this.scrollBarWidth !== undefined) {
202   - document.body.style.paddingRight = `${this.scrollBarWidth}px`;
203   - }
204   - },
205   - resetScrollBar () {
206   - document.body.style.paddingRight = '';
207   - },
208   - addScrollEffect () {
209   - this.checkScrollBar();
210   - this.setScrollBar();
211   - document.body.style.overflow = 'hidden';
212   - },
213   - removeScrollEffect() {
214   - document.body.style.overflow = '';
215   - this.resetScrollBar();
216   - },
217 189 animationFinish() {
218 190 this.$emit('on-hidden');
219 191 }
... ...
src/components/spin/index.js
1   -import Spin from './spin.vue';
  1 +import Spin from './spin.js';
  2 +
  3 +let spinInstance;
  4 +
  5 +function getSpinInstance (render = undefined) {
  6 + spinInstance = spinInstance || Spin.newInstance({
  7 + render: render
  8 + });
  9 +
  10 + return spinInstance;
  11 +}
  12 +
  13 +function loading (options) {
  14 + const render = ('render' in options) ? options.render : undefined;
  15 + let instance = getSpinInstance(render);
  16 +
  17 + instance.show(options);
  18 +}
  19 +
  20 +Spin.show = function (props = {}) {
  21 + return loading(props);
  22 +};
  23 +Spin.hide = function () {
  24 + if (!spinInstance) return false;
  25 +
  26 + const instance = getSpinInstance();
  27 +
  28 + instance.remove(() => {
  29 + spinInstance = null;
  30 + });
  31 +};
  32 +
2 33 export default Spin;
3 34 \ No newline at end of file
... ...
src/components/spin/spin.js 0 → 100644
  1 +import Vue from 'vue';
  2 +import Spin from './spin.vue';
  3 +
  4 +Spin.newInstance = properties => {
  5 + const _props = properties || {};
  6 +
  7 + const Instance = new Vue({
  8 + data: Object.assign({}, _props, {
  9 +
  10 + }),
  11 + render (h) {
  12 + let vnode = '';
  13 + if (this.render) {
  14 + vnode = h(Spin, {
  15 + props: {
  16 + fix: true,
  17 + fullscreen: true
  18 + }
  19 + }, [this.render(h)]);
  20 + } else {
  21 + vnode = h(Spin, {
  22 + props: {
  23 + size: 'large',
  24 + fix: true,
  25 + fullscreen: true
  26 + }
  27 + });
  28 + }
  29 + return h('div', {
  30 + 'class': 'ivu-spin-fullscreen'
  31 + }, [vnode]);
  32 + }
  33 + });
  34 +
  35 + const component = Instance.$mount();
  36 + document.body.appendChild(component.$el);
  37 + const spin = Instance.$children[0];
  38 +
  39 + return {
  40 + show () {
  41 + spin.visible = true;
  42 + },
  43 + remove (cb) {
  44 + spin.visible = false;
  45 + setTimeout(function() {
  46 + spin.$parent.$destroy();
  47 + document.body.removeChild(document.getElementsByClassName('ivu-spin-fullscreen')[0]);
  48 + cb();
  49 + }, 500);
  50 + },
  51 + component: spin
  52 + };
  53 +};
  54 +
  55 +export default Spin;
0 56 \ No newline at end of file
... ...
src/components/spin/spin.vue
1 1 <template>
2 2 <transition name="fade">
3   - <div :class="classes">
  3 + <div :class="classes" v-if="fullscreenVisible">
4 4 <div :class="mainClasses">
5 5 <span :class="dotClasses"></span>
6 6 <div :class="textClasses"><slot></slot></div>
... ... @@ -10,11 +10,13 @@
10 10 </template>
11 11 <script>
12 12 import { oneOf } from '../../utils/assist';
  13 + import ScrollbarMixins from '../modal/mixins-scrollbar';
13 14  
14 15 const prefixCls = 'ivu-spin';
15 16  
16 17 export default {
17 18 name: 'Spin',
  19 + mixins: [ ScrollbarMixins ],
18 20 props: {
19 21 size: {
20 22 validator (value) {
... ... @@ -24,11 +26,17 @@
24 26 fix: {
25 27 type: Boolean,
26 28 default: false
  29 + },
  30 + fullscreen: {
  31 + type: Boolean,
  32 + default: false
27 33 }
28 34 },
29 35 data () {
30 36 return {
31   - showText: false
  37 + showText: false,
  38 + // used for $Spin
  39 + visible: false
32 40 };
33 41 },
34 42 computed: {
... ... @@ -39,6 +47,7 @@
39 47 [`${prefixCls}-${this.size}`]: !!this.size,
40 48 [`${prefixCls}-fix`]: this.fix,
41 49 [`${prefixCls}-show-text`]: this.showText,
  50 + [`${prefixCls}-fullscreen`]: this.fullscreen
42 51 }
43 52 ];
44 53 },
... ... @@ -50,6 +59,22 @@
50 59 },
51 60 textClasses () {
52 61 return `${prefixCls}-text`;
  62 + },
  63 + fullscreenVisible () {
  64 + if (this.fullscreen) {
  65 + return this.visible;
  66 + } else {
  67 + return true;
  68 + }
  69 + }
  70 + },
  71 + watch: {
  72 + visible (val) {
  73 + if (val) {
  74 + this.addScrollEffect();
  75 + } else {
  76 + this.removeScrollEffect();
  77 + }
53 78 }
54 79 },
55 80 mounted () {
... ...
src/index.js
... ... @@ -139,6 +139,7 @@ const install = function (Vue, opts = {}) {
139 139 Vue.prototype.$Message = Message;
140 140 Vue.prototype.$Modal = Modal;
141 141 Vue.prototype.$Notice = Notice;
  142 + Vue.prototype.$Spin = Spin;
142 143 };
143 144  
144 145 // auto install
... ...
src/styles/components/spin.less
... ... @@ -33,6 +33,9 @@
33 33 .square(100%);
34 34 background-color: rgba(255,255,255,.9);
35 35 }
  36 + &-fullscreen{
  37 + z-index: @zindex-spin-fullscreen;
  38 + }
36 39  
37 40 &-fix &-main {
38 41 position: absolute;
... ...
src/styles/custom.less
... ... @@ -149,6 +149,7 @@
149 149 @zindex-tooltip : 1060;
150 150 @zindex-transfer : 1060;
151 151 @zindex-loading-bar : 2000;
  152 +@zindex-spin-fullscreen : 2010;
152 153  
153 154 // Animation
154 155 @animation-time : .3s;
... ...