vue3 v-loading指令封装

Thursday , 2022-5-05 17:15

最近用 Arco Design 发现它除了button组件,其他并没有封装v-loading的指令,遂自己封装之

思路是先做个loading状态的hook,然后封装v-loading指令用于控制

Loading hook封装

1
2
3
4
5
6
7
8
9
10
11
12
//文件新建 src/hooks/useLoading.ts
import { ref } from 'vue';
export default function useLoading() {
const loading = ref<boolean>(false);
const setLoading = (type:boolean)=>{
loading.value = type;
}
return {
setLoading,
loading
};
}

v-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
// 新建文件  src/directives/loading/index.vue
<template>
<div class="loading-container">
<icon-loading />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { IconLoading } from '@arco-design/web-vue/es/icon';
export default defineComponent({
components:{
IconLoading
},
setup() {

},
});
</script>
<style lang="scss" scoped>
.loading-container{
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
overflow: hidden;
background: rgba($color: #ffffff, $alpha: 0.7);
display: flex;
justify-content: center;
align-items: center;
font-size: 50px;
color: #335dfd;
}
</style>
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
// 新建文件  src/directives/loading/index.ts

import {createApp, Directive } from 'vue';
import Loading from './index.vue';

const loading: Directive = {
mounted(el,binding){
const app = createApp(Loading);
const instance = app.mount(document.createElement('div'));
el.instance = instance;
el.style.position = 'relative';
if (binding.value) {
appendEl(el);
}
},
updated(el,binding) {
if (binding.value !== binding.oldValue) {
binding.value ? appendEl(el) : removeEl(el);
}
},
};

const appendEl = (el: { appendChild: (arg0: any) => void; instance: { $el: any; }; }) =>{
el.appendChild(el.instance.$el);
};

const removeEl = (el: { removeChild: (arg0: any) => void; instance: { $el: any; }; }) =>{
el.removeChild(el.instance.$el);
};

export default loading;
1
2
3
4
5
6
7
8
9
10
11
12
// src/main.ts 导入

import { createApp } from "vue";
import App from "./App.vue";

import loading from '@/directives/loading';
const app = createApp(App);

// 全局指令的使用
app.directive('loading',loading);

app.mount("#app");

在组件中使用

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
<template>
<div class="testBox" v-loading="loading">加载测试</div>
</template>

<script lang="ts">
import { defineComponent, ref,} from "vue";
import useLoading from '@/hooks/useLoading';
export default defineComponent({
setup() {
const {loading,setLoading} = useLoading();
setLoading(true);
setTimeout(() => {
setLoading(false);
}, 5000);
return {
loading
};
}
});
</script>

<style lang="scss" scoped>
.testBox{
display: block;
padding: 50px;
text-align: center;
text-align: center;
}
</style>