最近用 Arco Design 发现它除了button
组件,其他并没有封装v-loading
的指令,遂自己封装之
思路是先做个loading状态的hook,然后封装v-loading
指令用于控制
Loading hook封装
1 2 3 4 5 6 7 8 9 10 11 12
| 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
| <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
|
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
|
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>
|