cbvirtua 1.0.35 → 1.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/ske.txt +76 -0
- package/src/dom.js +227 -0
- package/src/index.js +106 -0
- package/src//346/226/260/345/273/272 /346/226/207/346/234/254/346/226/207/346/241/243.txt" +125 -0
- package/src/App.vue +0 -38
- package/src/assets/logo.png +0 -0
- package/src/components/HelloWorld.vue +0 -37
- package/src/components/cache.js +0 -1
- package/src/components/cache.vue +0 -70
- package/src/main.js +0 -8
package/package.json
CHANGED
package/ske.txt
CHANGED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 网页空闲检测
|
|
3
|
+
* @param {() => void} callback 空闲时执行,即一定时长无操作时触发
|
|
4
|
+
* @param {number} [timeout=15] 时长,默认15s,单位:秒
|
|
5
|
+
* @param {boolean} [immediate=false] 是否立即开始,默认 false
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
const onIdleDetection = (callback, timeout = 15, immediate = false) => {
|
|
9
|
+
let pageTimer;
|
|
10
|
+
let beginTime = 0;
|
|
11
|
+
const onClearTimer = () => {
|
|
12
|
+
pageTimer && clearTimeout(pageTimer);
|
|
13
|
+
pageTimer = undefined;
|
|
14
|
+
};
|
|
15
|
+
const onStartTimer = () => {
|
|
16
|
+
const currentTime = Date.now();
|
|
17
|
+
if (pageTimer && currentTime - beginTime < 100) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
onClearTimer();
|
|
22
|
+
beginTime = currentTime;
|
|
23
|
+
pageTimer = setTimeout(() => {
|
|
24
|
+
callback();
|
|
25
|
+
}, timeout * 1000);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const onPageVisibility = () => {
|
|
29
|
+
// 页面显示状态改变时,移除延时器
|
|
30
|
+
onClearTimer();
|
|
31
|
+
|
|
32
|
+
if (document.visibilityState === 'visible') {
|
|
33
|
+
const currentTime = Date.now();
|
|
34
|
+
// 页面显示时,计算时间,如果超出限制时间则直接执行回调函数
|
|
35
|
+
if (currentTime - beginTime >= timeout * 1000) {
|
|
36
|
+
callback();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// 继续计时
|
|
40
|
+
pageTimer = setTimeout(() => {
|
|
41
|
+
callback();
|
|
42
|
+
}, timeout * 1000 - (currentTime - beginTime));
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const startDetection = () => {
|
|
47
|
+
onStartTimer();
|
|
48
|
+
document.addEventListener('keydown', onStartTimer);
|
|
49
|
+
document.addEventListener('mousemove', onStartTimer);
|
|
50
|
+
document.addEventListener('visibilitychange', onPageVisibility);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const stopDetection = () => {
|
|
54
|
+
onClearTimer();
|
|
55
|
+
document.removeEventListener('keydown', onStartTimer);
|
|
56
|
+
document.removeEventListener('mousemove', onStartTimer);
|
|
57
|
+
document.removeEventListener('visibilitychange', onPageVisibility);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const restartDetection = () => {
|
|
61
|
+
onClearTimer();
|
|
62
|
+
onStartTimer();
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
if (immediate) {
|
|
66
|
+
startDetection();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
startDetection,
|
|
71
|
+
stopDetection,
|
|
72
|
+
restartDetection
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
|
package/src/dom.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/* istanbul ignore next */
|
|
2
|
+
|
|
3
|
+
import Vue from 'vue';
|
|
4
|
+
|
|
5
|
+
const isServer = Vue.prototype.$isServer;
|
|
6
|
+
const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
|
|
7
|
+
const MOZ_HACK_REGEXP = /^moz([A-Z])/;
|
|
8
|
+
const ieVersion = isServer ? 0 : Number(document.documentMode);
|
|
9
|
+
|
|
10
|
+
/* istanbul ignore next */
|
|
11
|
+
const trim = function(string) {
|
|
12
|
+
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '');
|
|
13
|
+
};
|
|
14
|
+
/* istanbul ignore next */
|
|
15
|
+
const camelCase = function(name) {
|
|
16
|
+
return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
|
|
17
|
+
return offset ? letter.toUpperCase() : letter;
|
|
18
|
+
}).replace(MOZ_HACK_REGEXP, 'Moz$1');
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/* istanbul ignore next */
|
|
22
|
+
export const on = (function() {
|
|
23
|
+
if (!isServer && document.addEventListener) {
|
|
24
|
+
return function(element, event, handler) {
|
|
25
|
+
if (element && event && handler) {
|
|
26
|
+
element.addEventListener(event, handler, false);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
} else {
|
|
30
|
+
return function(element, event, handler) {
|
|
31
|
+
if (element && event && handler) {
|
|
32
|
+
element.attachEvent('on' + event, handler);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
})();
|
|
37
|
+
|
|
38
|
+
/* istanbul ignore next */
|
|
39
|
+
export const off = (function() {
|
|
40
|
+
if (!isServer && document.removeEventListener) {
|
|
41
|
+
return function(element, event, handler) {
|
|
42
|
+
if (element && event) {
|
|
43
|
+
element.removeEventListener(event, handler, false);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
} else {
|
|
47
|
+
return function(element, event, handler) {
|
|
48
|
+
if (element && event) {
|
|
49
|
+
element.detachEvent('on' + event, handler);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
})();
|
|
54
|
+
|
|
55
|
+
/* istanbul ignore next */
|
|
56
|
+
export const once = function(el, event, fn) {
|
|
57
|
+
var listener = function() {
|
|
58
|
+
if (fn) {
|
|
59
|
+
fn.apply(this, arguments);
|
|
60
|
+
}
|
|
61
|
+
off(el, event, listener);
|
|
62
|
+
};
|
|
63
|
+
on(el, event, listener);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/* istanbul ignore next */
|
|
67
|
+
export function hasClass(el, cls) {
|
|
68
|
+
if (!el || !cls) return false;
|
|
69
|
+
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
|
|
70
|
+
if (el.classList) {
|
|
71
|
+
return el.classList.contains(cls);
|
|
72
|
+
} else {
|
|
73
|
+
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/* istanbul ignore next */
|
|
78
|
+
export function addClass(el, cls) {
|
|
79
|
+
if (!el) return;
|
|
80
|
+
var curClass = el.className;
|
|
81
|
+
var classes = (cls || '').split(' ');
|
|
82
|
+
|
|
83
|
+
for (var i = 0, j = classes.length; i < j; i++) {
|
|
84
|
+
var clsName = classes[i];
|
|
85
|
+
if (!clsName) continue;
|
|
86
|
+
|
|
87
|
+
if (el.classList) {
|
|
88
|
+
el.classList.add(clsName);
|
|
89
|
+
} else if (!hasClass(el, clsName)) {
|
|
90
|
+
curClass += ' ' + clsName;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!el.classList) {
|
|
94
|
+
el.setAttribute('class', curClass);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/* istanbul ignore next */
|
|
99
|
+
export function removeClass(el, cls) {
|
|
100
|
+
if (!el || !cls) return;
|
|
101
|
+
var classes = cls.split(' ');
|
|
102
|
+
var curClass = ' ' + el.className + ' ';
|
|
103
|
+
|
|
104
|
+
for (var i = 0, j = classes.length; i < j; i++) {
|
|
105
|
+
var clsName = classes[i];
|
|
106
|
+
if (!clsName) continue;
|
|
107
|
+
|
|
108
|
+
if (el.classList) {
|
|
109
|
+
el.classList.remove(clsName);
|
|
110
|
+
} else if (hasClass(el, clsName)) {
|
|
111
|
+
curClass = curClass.replace(' ' + clsName + ' ', ' ');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (!el.classList) {
|
|
115
|
+
el.setAttribute('class', trim(curClass));
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/* istanbul ignore next */
|
|
120
|
+
export const getStyle = ieVersion < 9 ? function(element, styleName) {
|
|
121
|
+
if (isServer) return;
|
|
122
|
+
if (!element || !styleName) return null;
|
|
123
|
+
styleName = camelCase(styleName);
|
|
124
|
+
if (styleName === 'float') {
|
|
125
|
+
styleName = 'styleFloat';
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
switch (styleName) {
|
|
129
|
+
case 'opacity':
|
|
130
|
+
try {
|
|
131
|
+
return element.filters.item('alpha').opacity / 100;
|
|
132
|
+
} catch (e) {
|
|
133
|
+
return 1.0;
|
|
134
|
+
}
|
|
135
|
+
default:
|
|
136
|
+
return (element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null);
|
|
137
|
+
}
|
|
138
|
+
} catch (e) {
|
|
139
|
+
return element.style[styleName];
|
|
140
|
+
}
|
|
141
|
+
} : function(element, styleName) {
|
|
142
|
+
if (isServer) return;
|
|
143
|
+
if (!element || !styleName) return null;
|
|
144
|
+
styleName = camelCase(styleName);
|
|
145
|
+
if (styleName === 'float') {
|
|
146
|
+
styleName = 'cssFloat';
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
var computed = document.defaultView.getComputedStyle(element, '');
|
|
150
|
+
return element.style[styleName] || computed ? computed[styleName] : null;
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return element.style[styleName];
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/* istanbul ignore next */
|
|
157
|
+
export function setStyle(element, styleName, value) {
|
|
158
|
+
if (!element || !styleName) return;
|
|
159
|
+
|
|
160
|
+
if (typeof styleName === 'object') {
|
|
161
|
+
for (var prop in styleName) {
|
|
162
|
+
if (styleName.hasOwnProperty(prop)) {
|
|
163
|
+
setStyle(element, prop, styleName[prop]);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
} else {
|
|
167
|
+
styleName = camelCase(styleName);
|
|
168
|
+
if (styleName === 'opacity' && ieVersion < 9) {
|
|
169
|
+
element.style.filter = isNaN(value) ? '' : 'alpha(opacity=' + value * 100 + ')';
|
|
170
|
+
} else {
|
|
171
|
+
element.style[styleName] = value;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export const isScroll = (el, vertical) => {
|
|
177
|
+
if (isServer) return;
|
|
178
|
+
|
|
179
|
+
const determinedDirection = vertical !== null && vertical !== undefined;
|
|
180
|
+
const overflow = determinedDirection
|
|
181
|
+
? vertical
|
|
182
|
+
? getStyle(el, 'overflow-y')
|
|
183
|
+
: getStyle(el, 'overflow-x')
|
|
184
|
+
: getStyle(el, 'overflow');
|
|
185
|
+
|
|
186
|
+
return overflow.match(/(scroll|auto|overlay)/);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export const getScrollContainer = (el, vertical) => {
|
|
190
|
+
if (isServer) return;
|
|
191
|
+
|
|
192
|
+
let parent = el;
|
|
193
|
+
while (parent) {
|
|
194
|
+
if ([window, document, document.documentElement].includes(parent)) {
|
|
195
|
+
return window;
|
|
196
|
+
}
|
|
197
|
+
if (isScroll(parent, vertical)) {
|
|
198
|
+
return parent;
|
|
199
|
+
}
|
|
200
|
+
parent = parent.parentNode;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return parent;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export const isInContainer = (el, container) => {
|
|
207
|
+
if (isServer || !el || !container) return false;
|
|
208
|
+
|
|
209
|
+
const elRect = el.getBoundingClientRect();
|
|
210
|
+
let containerRect;
|
|
211
|
+
|
|
212
|
+
if ([window, document, document.documentElement, null, undefined].includes(container)) {
|
|
213
|
+
containerRect = {
|
|
214
|
+
top: 0,
|
|
215
|
+
right: window.innerWidth,
|
|
216
|
+
bottom: window.innerHeight,
|
|
217
|
+
left: 0
|
|
218
|
+
};
|
|
219
|
+
} else {
|
|
220
|
+
containerRect = container.getBoundingClientRect();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return elRect.top < containerRect.bottom &&
|
|
224
|
+
elRect.bottom > containerRect.top &&
|
|
225
|
+
elRect.right > containerRect.left &&
|
|
226
|
+
elRect.left < containerRect.right;
|
|
227
|
+
};
|
package/src/index.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import Vue from 'vue';
|
|
2
|
+
import loadingVue from './loading.vue';
|
|
3
|
+
import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom';
|
|
4
|
+
import { PopupManager } from 'element-ui/src/utils/popup';
|
|
5
|
+
import afterLeave from 'element-ui/src/utils/after-leave';
|
|
6
|
+
import merge from 'element-ui/src/utils/merge';
|
|
7
|
+
|
|
8
|
+
const LoadingConstructor = Vue.extend(loadingVue);
|
|
9
|
+
|
|
10
|
+
const defaults = {
|
|
11
|
+
text: null,
|
|
12
|
+
fullscreen: true,
|
|
13
|
+
body: false,
|
|
14
|
+
lock: false,
|
|
15
|
+
customClass: ''
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
let fullscreenLoading;
|
|
19
|
+
|
|
20
|
+
LoadingConstructor.prototype.originalPosition = '';
|
|
21
|
+
LoadingConstructor.prototype.originalOverflow = '';
|
|
22
|
+
|
|
23
|
+
LoadingConstructor.prototype.close = function() {
|
|
24
|
+
if (this.fullscreen) {
|
|
25
|
+
fullscreenLoading = undefined;
|
|
26
|
+
}
|
|
27
|
+
afterLeave(this, _ => {
|
|
28
|
+
const target = this.fullscreen || this.body
|
|
29
|
+
? document.body
|
|
30
|
+
: this.target;
|
|
31
|
+
removeClass(target, 'el-loading-parent--relative');
|
|
32
|
+
removeClass(target, 'el-loading-parent--hidden');
|
|
33
|
+
if (this.$el && this.$el.parentNode) {
|
|
34
|
+
this.$el.parentNode.removeChild(this.$el);
|
|
35
|
+
}
|
|
36
|
+
this.$destroy();
|
|
37
|
+
}, 300);
|
|
38
|
+
this.visible = false;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const addStyle = (options, parent, instance) => {
|
|
42
|
+
let maskStyle = {};
|
|
43
|
+
if (options.fullscreen) {
|
|
44
|
+
instance.originalPosition = getStyle(document.body, 'position');
|
|
45
|
+
instance.originalOverflow = getStyle(document.body, 'overflow');
|
|
46
|
+
maskStyle.zIndex = PopupManager.nextZIndex();
|
|
47
|
+
} else if (options.body) {
|
|
48
|
+
instance.originalPosition = getStyle(document.body, 'position');
|
|
49
|
+
['top', 'left'].forEach(property => {
|
|
50
|
+
let scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
|
|
51
|
+
maskStyle[property] = options.target.getBoundingClientRect()[property] +
|
|
52
|
+
document.body[scroll] +
|
|
53
|
+
document.documentElement[scroll] +
|
|
54
|
+
'px';
|
|
55
|
+
});
|
|
56
|
+
['height', 'width'].forEach(property => {
|
|
57
|
+
maskStyle[property] = options.target.getBoundingClientRect()[property] + 'px';
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
instance.originalPosition = getStyle(parent, 'position');
|
|
61
|
+
}
|
|
62
|
+
Object.keys(maskStyle).forEach(property => {
|
|
63
|
+
instance.$el.style[property] = maskStyle[property];
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const Loading = (options = {}) => {
|
|
68
|
+
if (Vue.prototype.$isServer) return;
|
|
69
|
+
options = merge({}, defaults, options);
|
|
70
|
+
if (typeof options.target === 'string') {
|
|
71
|
+
options.target = document.querySelector(options.target);
|
|
72
|
+
}
|
|
73
|
+
options.target = options.target || document.body;
|
|
74
|
+
if (options.target !== document.body) {
|
|
75
|
+
options.fullscreen = false;
|
|
76
|
+
} else {
|
|
77
|
+
options.body = true;
|
|
78
|
+
}
|
|
79
|
+
if (options.fullscreen && fullscreenLoading) {
|
|
80
|
+
return fullscreenLoading;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let parent = options.body ? document.body : options.target;
|
|
84
|
+
let instance = new LoadingConstructor({
|
|
85
|
+
el: document.createElement('div'),
|
|
86
|
+
data: options
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
addStyle(options, parent, instance);
|
|
90
|
+
if (instance.originalPosition !== 'absolute' && instance.originalPosition !== 'fixed' && instance.originalPosition !== 'sticky') {
|
|
91
|
+
addClass(parent, 'el-loading-parent--relative');
|
|
92
|
+
}
|
|
93
|
+
if (options.fullscreen && options.lock) {
|
|
94
|
+
addClass(parent, 'el-loading-parent--hidden');
|
|
95
|
+
}
|
|
96
|
+
parent.appendChild(instance.$el);
|
|
97
|
+
Vue.nextTick(() => {
|
|
98
|
+
instance.visible = true;
|
|
99
|
+
});
|
|
100
|
+
if (options.fullscreen) {
|
|
101
|
+
fullscreenLoading = instance;
|
|
102
|
+
}
|
|
103
|
+
return instance;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export default Loading;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="recommendPage">
|
|
3
|
+
<swiper :options="swiperOption" ref="mySwiper">
|
|
4
|
+
<swiper-slide>I'm Slide 1</swiper-slide>
|
|
5
|
+
<swiper-slide>I'm Slide 2</swiper-slide>
|
|
6
|
+
<swiper-slide>I'm Slide 3</swiper-slide>
|
|
7
|
+
<div class="swiper-pagination" slot="pagination"></div>
|
|
8
|
+
<div class="swiper-button-prev" slot="button-prev"></div>
|
|
9
|
+
<div class="swiper-button-next" slot="button-next"></div>
|
|
10
|
+
</swiper>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
// 引入插件
|
|
16
|
+
import { swiper, swiperSlide } from "vue-awesome-swiper";
|
|
17
|
+
import "swiper/dist/css/swiper.css";
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
components: {
|
|
21
|
+
swiper,
|
|
22
|
+
swiperSlide
|
|
23
|
+
},
|
|
24
|
+
data() {
|
|
25
|
+
return {
|
|
26
|
+
swiperOption: {
|
|
27
|
+
loop: true,
|
|
28
|
+
autoplay: {
|
|
29
|
+
delay: 3000,
|
|
30
|
+
stopOnLastSlide: false,
|
|
31
|
+
disableOnInteraction: false
|
|
32
|
+
},
|
|
33
|
+
// 显示分页
|
|
34
|
+
pagination: {
|
|
35
|
+
el: ".swiper-pagination",
|
|
36
|
+
clickable: true //允许分页点击跳转
|
|
37
|
+
},
|
|
38
|
+
// 设置点击箭头
|
|
39
|
+
navigation: {
|
|
40
|
+
nextEl: ".swiper-button-next",
|
|
41
|
+
prevEl: ".swiper-button-prev"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
computed: {
|
|
47
|
+
swiper() {
|
|
48
|
+
return this.$refs.mySwiper.swiper;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
mounted() {
|
|
52
|
+
// current swiper instance
|
|
53
|
+
// 然后你就可以使用当前上下文内的swiper对象去做你想做的事了
|
|
54
|
+
console.log("this is current swiper instance object", this.swiper);
|
|
55
|
+
// this.swiper.slideTo(3, 1000, false);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
</script>
|
|
59
|
+
<style scoped >
|
|
60
|
+
.recommendPage .swiper-container{
|
|
61
|
+
position: relative;
|
|
62
|
+
width: 100%;
|
|
63
|
+
height: 200px;
|
|
64
|
+
background: pink;
|
|
65
|
+
}
|
|
66
|
+
.recommendPage .swiper-container .swiper-slide{
|
|
67
|
+
width: 100%;
|
|
68
|
+
line-height: 200px;
|
|
69
|
+
background: yellowgreen;
|
|
70
|
+
color: #000;
|
|
71
|
+
font-size: 16px;
|
|
72
|
+
text-align: center;
|
|
73
|
+
}
|
|
74
|
+
</style>
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
//index.js
|
|
78
|
+
import myLoading from './loading.vue';
|
|
79
|
+
export default {
|
|
80
|
+
/*
|
|
81
|
+
* Vue:Vue 构造器
|
|
82
|
+
* options:可选插件参数
|
|
83
|
+
*/
|
|
84
|
+
install(Vue, options) {
|
|
85
|
+
/*
|
|
86
|
+
*Vue.extend: https://cn.vuejs.org/v2/api/#Vue-extend
|
|
87
|
+
*使用基础 Vue.extend 构造器,创建一个“子类” (Loading)。参数是一个包含组件选项的对象(myLoading)。
|
|
88
|
+
*然后 创建一个 Loading 的实例 Profile 挂载到一个HTMLElement实例上
|
|
89
|
+
*/
|
|
90
|
+
const Loading = Vue.extend(myLoading);
|
|
91
|
+
const Profile = new Loading({
|
|
92
|
+
el: document.createElement('div')
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
/*
|
|
96
|
+
*el: https://cn.vuejs.org/v2/api/#el
|
|
97
|
+
*loading.vue中的template模板内容将会替换挂载的元素。挂载元素的内容都将被忽略。 *所以Profile.$el最终是template里面的内容
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
//插入到 document.body
|
|
101
|
+
document.body.appendChild(Profile.$el);
|
|
102
|
+
|
|
103
|
+
//这里插件接收三个值 icon progressColor 如果注册的时候传入这些值则赋值给组件内默认值。
|
|
104
|
+
if(options){
|
|
105
|
+
if(options.icon)
|
|
106
|
+
Profile.icon = options.icon;
|
|
107
|
+
if(options.progressColor)
|
|
108
|
+
Profile.progressColor = options.progressColor;
|
|
109
|
+
}
|
|
110
|
+
//定义显示隐藏的方法 open 会传入一个text 字符串。如果有则赋值给组件内默认值。
|
|
111
|
+
const myLoadingMethod = {
|
|
112
|
+
open(text) {
|
|
113
|
+
Profile.show = true;
|
|
114
|
+
if(text){
|
|
115
|
+
Profile.text = text;
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
hide() {
|
|
119
|
+
Profile.show = false;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
//添加实例方法 把自定义方法挂载到Vue构造器的上,这样每个实例都可以调用。
|
|
123
|
+
Vue.prototype.$myLoading = myLoadingMethod;
|
|
124
|
+
}
|
|
125
|
+
}
|
package/src/App.vue
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div id="app">
|
|
3
|
-
<div @click="show = !show" style="border:1px solid #f0f;">测试</div>
|
|
4
|
-
<HelloWorld msg="Welcome to Your Vue.js App" />
|
|
5
|
-
<vCahe v-if="show">
|
|
6
|
-
<HelloWorld msg="Welcome to Your Vue.js App" />
|
|
7
|
-
</vCahe>
|
|
8
|
-
</div>
|
|
9
|
-
</template>
|
|
10
|
-
|
|
11
|
-
<script>
|
|
12
|
-
import HelloWorld from './components/HelloWorld.vue'
|
|
13
|
-
import vCahe from './components/cache.vue'
|
|
14
|
-
|
|
15
|
-
export default {
|
|
16
|
-
name: 'App',
|
|
17
|
-
data() {
|
|
18
|
-
return {
|
|
19
|
-
show: true
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
components: {
|
|
23
|
-
HelloWorld,
|
|
24
|
-
vCahe
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
</script>
|
|
28
|
-
|
|
29
|
-
<style>
|
|
30
|
-
#app {
|
|
31
|
-
font-family: Avenir, Helvetica, Arial, sans-serif;
|
|
32
|
-
-webkit-font-smoothing: antialiased;
|
|
33
|
-
-moz-osx-font-smoothing: grayscale;
|
|
34
|
-
text-align: center;
|
|
35
|
-
color: #2c3e50;
|
|
36
|
-
margin-top: 60px;
|
|
37
|
-
}
|
|
38
|
-
</style>
|
package/src/assets/logo.png
DELETED
|
Binary file
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="hello">
|
|
3
|
-
<input type="text" v-model="name">
|
|
4
|
-
</div>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script>
|
|
8
|
-
export default {
|
|
9
|
-
name: 'HelloWorld',
|
|
10
|
-
data() {
|
|
11
|
-
return {
|
|
12
|
-
name: 123
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
</script>
|
|
17
|
-
|
|
18
|
-
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
19
|
-
<style scoped>
|
|
20
|
-
h3 {
|
|
21
|
-
margin: 40px 0 0;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
ul {
|
|
25
|
-
list-style-type: none;
|
|
26
|
-
padding: 0;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
li {
|
|
30
|
-
display: inline-block;
|
|
31
|
-
margin: 0 10px;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
a {
|
|
35
|
-
color: #42b983;
|
|
36
|
-
}
|
|
37
|
-
</style>
|
package/src/components/cache.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default {}
|
package/src/components/cache.vue
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
function getComponentName(opts) {
|
|
3
|
-
return opts && (opts.Ctor.options.name || opts.tag)
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
function isDef(v) {
|
|
7
|
-
return v !== undefined && v !== null
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function isAsyncPlaceholder(node) {
|
|
11
|
-
return node.isComment && node.asyncFactory
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function getFirstComponentChild(children) {
|
|
15
|
-
if (Array.isArray(children)) {
|
|
16
|
-
for (let i = 0; i < children.length; i++) {
|
|
17
|
-
const c = children[i]
|
|
18
|
-
if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
|
|
19
|
-
return c
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
import cache from './cache'
|
|
25
|
-
export default {
|
|
26
|
-
name: 'v-cache',
|
|
27
|
-
abstract: true,
|
|
28
|
-
|
|
29
|
-
props: {
|
|
30
|
-
cacheKey: {
|
|
31
|
-
type: String,
|
|
32
|
-
required: true
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
data() {
|
|
37
|
-
return {
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
render() {
|
|
42
|
-
const slot = this.$slots.default
|
|
43
|
-
const vnode = getFirstComponentChild(slot)
|
|
44
|
-
const componentOptions = vnode && vnode.componentOptions
|
|
45
|
-
|
|
46
|
-
if (componentOptions) {
|
|
47
|
-
const name = getComponentName(componentOptions)
|
|
48
|
-
const { cacheKey } = this
|
|
49
|
-
const key = name + cacheKey
|
|
50
|
-
|
|
51
|
-
vnode.key = key
|
|
52
|
-
|
|
53
|
-
if (cache[key]) {
|
|
54
|
-
vnode.componentInstance = cache[key].componentInstance
|
|
55
|
-
} else {
|
|
56
|
-
cache[key] = vnode
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
vnode.data.keepAlive = true
|
|
60
|
-
}
|
|
61
|
-
return vnode || (slot && slot[0])
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
destroyed() {
|
|
65
|
-
// Object.values(cache).forEach(vnode => {
|
|
66
|
-
// vnode.componentInstance.$destroy()
|
|
67
|
-
// })
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
</script>
|