书接上文 咱们开发了一个loading组件, 但这样使用并不能满足我们的需求
可以通过js直接调用方法来显示关闭
loading可以将整个页面全部遮罩起来
# 通过Vue.extend将组件转换为全局组件
- 改造loading组件,将组件的props改为data
export default {
data() {
return {
text: '',
visible: false
}
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 通过Vue.extend改造组件
// loading/index.js
import Vue from 'vue'
import LoadingComponent from './loading.vue'
// 通过Vue.extend将组件包装成一个子类
const LoadingConstructor = Vue.extend(LoadingComponent)
let loading = undefined
LoadingConstructor.prototype.close = function() {
// 如果loading 有引用,则去掉引用
if (loading) {
loading = undefined
}
// 先将组件隐藏
this.visible = false
// 延迟300毫秒,等待loading关闭动画执行完之后销毁组件
setTimeout(() => {
// 移除挂载的dom元素
if (this.$el && this.$el.parentNode) {
this.$el.parentNode.removeChild(this.$el)
}
// 调用组件的$destroy方法进行组件销毁
this.$destroy()
}, 300)
}
const Loading = (options = {}) => {
// 如果组件已渲染,则返回即可
if (loading) {
return loading
}
// 要挂载的元素
const parent = document.body
// 组件属性
const opts = {
text: '',
...options
}
// 通过构造函数初始化组件 相当于 new Vue()
const instance = new LoadingConstructor({
el: document.createElement('div'),
data: opts
})
// 将loading元素挂在到parent上面
parent.appendChild(instance.$el)
// 显示loading
Vue.nextTick(() => {
instance.visible = true
})
// 将组件实例赋值给loading
loading = instance
return instance
}
export default Loading
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
- 在页面使用loading
import Loading from './loading/index.js'
export default {
created() {
const loading = Loading({ text: '正在加载。。。' })
// 三秒钟后关闭
setTimeout(() => {
loading.close()
}, 3000)
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
通过上面的改造,loading已经可以在全局使用了,如果需要像element-ui一样挂载到Vue.prototype上面,通过this.$loading调用,还需要改造一下
Vue.prototype.$loading = Loading
// 在export之前将Loading方法进行绑定
export default Loading
// 在组件内使用
this.$loading()
1
2
3
4
5
6
2
3
4
5
6