如果让我实现一个v-loading,我该怎么办?

1、首先肯定要写出一个loading加载动画了
waiting.vue文件

<template>
	<div class="waiting_div">
		<div class="background_div">
		
			<span class="iconfont icon-jiazaidonghua">span>
			
		div>
	div>
template>
<script setup>
script>

<style scoped lang="less">
	.waiting_div {
	//注意了,我把它隐藏了!!!!!!!!!!!!
		visibility: hidden;
		position: fixed;
		.background_div {
			background-color: #fff;
			opacity: 0.8;
			width: 100%;
			height: 100%;
			display: flex;
			align-items: center;
			justify-content: center;
			.iconfont {
				font-size: 50px;
				color: #297aff;
				animation: icon_rotate 1.5s ease-in-out infinite alternate-reverse;
			}
		}
	}
	@keyframes icon_rotate {
		0% {
			transform: rotate(0deg);
		}
		100% {
			transform: rotate(480deg);
		}
	}
style>

2、注册自定义指令v-waiting

v_directive.js文件

// 注册vue自定义指令工具

/**
 * el 绑定元素dom
 * val 绑定的值
 * vnode 
 */
let _ = {

}
//设置waiting元素的样式,根据目标taregt样式进行设置
const set_waiting_style = (waiting_dom, target = {}) => {
    const bound = target.getBoundingClientRect()
    const { height, left, width, top } = bound
    waiting_dom.setAttribute('style', `
    width:${width}px;
    height: ${height}px;
    left:${left}px;
    top:${top}px;
    visibility:visible;
    `)
}
//清除waiting元素的样式,让其继续保持隐藏
const clear_waiting_style = (waiting_dom) => {
    if (waiting_dom) {
        waiting_dom.setAttribute('style', `
        visibility:hidden;
        `)
    }
}
// 自定义等待loading   v-waiting指令
//我个人是不推荐页面同时有多个loading的
const waiting = (Vue) => {
    Vue.directive('waiting', (el, val, vnode) => {
        if (val.value) {
            if (!_.waiting_dom) {
                const waiting_dom = document.querySelector(".waiting_div")
                _.waiting_dom = waiting_dom
            }
            set_waiting_style(_.waiting_dom, el)
        } else {
            clear_waiting_style(_.waiting_dom)
            return
        }
    })
}

const v_directive = (Vue) => {
    waiting(Vue)
}

export {
    v_directive
}

3、使用
main.js挂载自定义指令

import { createApp} from 'vue'
import App from './App.vue'
//...
//@utils/vue_instruct,是我自己的文件路径,@utils是我配置的快捷地址
import { v_directive } from '@utils/vue_instruct'

//...
const app = createApp(App)
app.use(router).use(v_directive).mount('#app')

app.vue使用loading组件


<template>
	<div class="contain" v-waiting="loading">
			
		<waiting />
	div>
template>
<script setup>
	import waiting from "@/components/card/waiting.vue";
	import { onMounted, ref } from "vue";
	
	onMounted(() => {
			setTimeout(() => {
			loading.value = false
		}, 2000);
	});
	const loading = ref(true);
script>

<style scoped lang='less'>
	.contain{
	height:600px
	}
style>

效果截图:
如果让我实现一个v-loading,我该怎么办?_第1张图片

4、问题:
不能同时存在多个loading:我个人的建议是一个页面尽量确保只有一个loading正在运行(并非只能写一个v-waiting,而是确保只有一个v-waiting正在运行),多个loading动画同时运行时。
如果非要同时运行多个loading,解决方案:
无需在app.vue中引入waiting 组件,而是在v_directive.js引入waiting组件,并且在绑定的loading值为false时移除waiting组件,在值为true时,向body或者某个元素上插入waiting组件
页面多个loading改为一个loading,解决方案:
有多个loading,无非是因为我们调取了多个接口,不想再接口数据未返回的时候让用户进行操作,建议用Promise.all进行解决。拿到所有接口成功的回调,再loading=false

你可能感兴趣的:(javascript,vue.js,开发语言)