初始版本提交

This commit is contained in:
yaoyn
2024-02-05 09:15:37 +08:00
parent b52d4414be
commit 445292105f
1848 changed files with 236859 additions and 75 deletions

View File

@ -0,0 +1,5 @@
import Loading from './src/Loading.vue';
export { Loading };
export { useLoading } from './src/useLoading';
export { createLoading } from './src/createLoading';

View File

@ -0,0 +1,79 @@
<template>
<section
class="full-loading"
:class="{ absolute, [theme]: !!theme }"
:style="[background ? `background-color: ${background}` : '']"
v-show="loading"
>
<Spin v-bind="$attrs" :tip="tip" :size="size" :spinning="loading" />
</section>
</template>
<script lang="ts">
import { PropType } from 'vue';
import { defineComponent } from 'vue';
import { Spin } from 'ant-design-vue';
import { SizeEnum } from '/@/enums/sizeEnum';
export default defineComponent({
name: 'Loading',
components: { Spin },
props: {
tip: {
type: String as PropType<string>,
default: '',
},
size: {
type: String as PropType<SizeEnum>,
default: SizeEnum.LARGE,
validator: (v: SizeEnum): boolean => {
return [SizeEnum.DEFAULT, SizeEnum.SMALL, SizeEnum.LARGE].includes(v);
},
},
absolute: {
type: Boolean as PropType<boolean>,
default: false,
},
loading: {
type: Boolean as PropType<boolean>,
default: false,
},
background: {
type: String as PropType<string>,
},
theme: {
type: String as PropType<'dark' | 'light'>,
},
},
});
</script>
<style lang="less" scoped>
.full-loading {
position: fixed;
top: 0;
left: 0;
z-index: 200;
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
background-color: rgb(240 242 245 / 40%);
&.absolute {
position: absolute;
top: 0;
left: 0;
z-index: 300;
}
}
html[data-theme='dark'] {
.full-loading:not(.light) {
background-color: @modal-mask-bg;
}
}
.full-loading.dark {
background-color: @modal-mask-bg;
}
</style>

View File

@ -0,0 +1,65 @@
import { VNode, defineComponent } from 'vue';
import type { LoadingProps } from './typing';
import { createVNode, render, reactive, h } from 'vue';
import Loading from './Loading.vue';
export function createLoading(props?: Partial<LoadingProps>, target?: HTMLElement, wait = false) {
let vm: Nullable<VNode> = null;
const data = reactive({
tip: '',
loading: true,
...props,
});
const LoadingWrap = defineComponent({
render() {
return h(Loading, { ...data });
},
});
vm = createVNode(LoadingWrap);
if (wait) {
// TODO fix https://github.com/anncwb/vue-vben-admin/issues/438
setTimeout(() => {
render(vm, document.createElement('div'));
}, 0);
} else {
render(vm, document.createElement('div'));
}
function close() {
if (vm?.el && vm.el.parentNode) {
vm.el.parentNode.removeChild(vm.el);
}
}
function open(target: HTMLElement = document.body) {
if (!vm || !vm.el) {
return;
}
target.appendChild(vm.el as HTMLElement);
}
if (target) {
open(target);
}
return {
vm,
close,
open,
setTip: (tip: string) => {
data.tip = tip;
},
setLoading: (loading: boolean) => {
data.loading = loading;
},
get loading() {
return data.loading;
},
get $el() {
return vm?.el as HTMLElement;
},
};
}

View File

@ -0,0 +1,10 @@
import { SizeEnum } from '/@/enums/sizeEnum';
export interface LoadingProps {
tip: string;
size: SizeEnum;
absolute: boolean;
loading: boolean;
background: string;
theme: 'dark' | 'light';
}

View File

@ -0,0 +1,49 @@
import { unref } from 'vue';
import { createLoading } from './createLoading';
import type { LoadingProps } from './typing';
import type { Ref } from 'vue';
export interface UseLoadingOptions {
target?: any;
props?: Partial<LoadingProps>;
}
interface Fn {
(): void;
}
export function useLoading(props: Partial<LoadingProps>): [Fn, Fn, (string) => void];
export function useLoading(opt: Partial<UseLoadingOptions>): [Fn, Fn, (string) => void];
export function useLoading(
opt: Partial<LoadingProps> | Partial<UseLoadingOptions>,
): [Fn, Fn, (string) => void] {
let props: Partial<LoadingProps>;
let target: HTMLElement | Ref<ElRef> = document.body;
if (Reflect.has(opt, 'target') || Reflect.has(opt, 'props')) {
const options = opt as Partial<UseLoadingOptions>;
props = options.props || {};
target = options.target || document.body;
} else {
props = opt as Partial<LoadingProps>;
}
const instance = createLoading(props, undefined, true);
const open = (): void => {
const t = unref(target as Ref<ElRef>);
if (!t) return;
instance.open(t);
};
const close = (): void => {
instance.close();
};
const setTip = (tip: string) => {
instance.setTip(tip);
};
return [open, close, setTip];
}