vue自定义指令v-loading(vue2和vue3)

这篇具有很好参考价值的文章主要介绍了vue自定义指令v-loading(vue2和vue3)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

效果

vue自定义指令v-loading(vue2和vue3)

 

vue2写法

1. 目录结构:

vue自定义指令v-loading(vue2和vue3)

2. 代码实现 

/directives/loading/loading.vue   loading效果页面(此处使用的antd下面的组件,可自定义)

<template>
    <div v-show="visible" class="loading-box">
      <a-spin tip="正在加载中,请耐心等待" />
    </div>
</template>

<script>
export default {
  data() {
    return {
      visible: false,
    };
  },
};
</script>
<style scoped lang="less">
.loading-box {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgb(0 0 0 / 20%);;

    position: absolute;
    top: 0;
    left: 0;
}
</style>

/directives/loading/loading.js(实现loading组件的插入及销毁)

import Vue from 'vue'
import Loading from './loading.vue'

const Mask = Vue.extend(Loading)

const toggleLoading = (el, binding) => {
    if (binding.value) {
        Vue.nextTick(() => {
            // 控制loading组件显示
            el.instance.visible = true
            // 插入到目标元素
            insertDom(el, el, binding)
        })
    } else {
        el.instance.visible = false
    }
}

const insertDom = (parent, el) => {
    // 给父元素加个定位,让loading元素定位
    el.style.position='relative';
    parent.appendChild(el.mask)
}

export default {
    bind: function (el, binding, vnode) {
        const mask = new Mask({
            el: document.createElement('div'),
            data() { }
        })
        el.instance = mask
        el.mask = mask.$el
        el.maskStyle = {}
        binding.value && toggleLoading(el, binding)
    },
    update: function (el, binding) {
        if (binding.oldValue !== binding.value) {
            toggleLoading(el, binding)
        }
    },
    unbind: function (el, binding) {
        el.style.position='';
        el.instance && el.instance.$destroy()
    }
}

/directives/loading/index.js(loading指令的注册)

import loading from './loading';
export default {
  install(Vue) {
    Vue.directive("loading", loading) // 全局loading
  }
}

3. 全局引入(main.js文件)

// 引入loading
import loading from './vue-tool/directives/loading' 
Vue.use(loading);

4. 使用

<div v-loading="isLoading">我是loading父元素(isLoading为控制loading展示的自定义变量)</div>

vue3写法

1. 目录结构

vue自定义指令v-loading(vue2和vue3)

2. 代码实现  

/directives/loading/index.vue   loading效果页面(此处使用的antd下面的组件,可自定义)

<template>
  <div class="loading-box">
    <a-spin tip="正在加载中,请耐心等待" />
  </div>
</template>

<script lang="ts" setup>
    import { } from 'vue';
</script>


<style scoped lang="less">
.loading-box {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgb(0 0 0 / 20%);

    position: absolute;
    top: 0;
    left: 0;
    :deep(.ant-spin-dot-item) {
      background-color: #FFF;
    }
    :deep(.ant-spin.ant-spin-show-text .ant-spin-text)  {
      color: #FFF;
    }
}
</style>

/directives/loading/index.ts(实现loading组件的插入及销毁)


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

export const loading: Directive = {
    mounted(el,binding){
        const app = createApp(Loading);
        const instance = app.mount(document.createElement('div'));
        el.instance = instance;
        if (binding.value) {
            appendEl(el);
        }
    },
    updated(el,binding) {
        if (binding.value !== binding.oldValue) {
            binding.value ? appendEl(el) : removeEl(el); 
        }
    },
};
// 插入元素
const appendEl = (el) =>{
    // 给父元素加个定位,让loading元素定位
    el.style.position='relative';
    el?.appendChild(el.instance.$el);
};
// 移除元素
const removeEl = (el) =>{
    el.style.position='';

    // 踩坑:el?.removeChild(el.instance.$el)->直接这样写会报错:Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.(要删除的节点不是此节点的子节点)
    // 解决:判断一下是否为此节点的子元素再移除(参考:https://www.freesion.com/article/2620879355/)
    let $el = el.instance.$el;
    if (el?.contains($el)) {
        el?.removeChild($el);
    }
};

/directives/index.ts

export * from './loading'

3. 全局引入(main.js文件)

// 循环注册指令
import * as directives from './tool/directives';
Object.keys(directives).forEach(key => {
  Vue.directive(key, (directives as { [key: string ]: Directive })[key]);
});

4. 使用 v-loading=“”

补充:a-spin为antd组件,显示不了的可以把a-spin部分替换为一个简单的loading效果组件,下面提供两种可直接使用的:

1. 效果1

vue自定义指令v-loading(vue2和vue3)

<template>
    <div class="ant-spin ant-spin-spinning">
        <span class="ant-spin-dot ant-spin-dot-spin">
            <i class="ant-spin-dot-item"></i>
            <i class="ant-spin-dot-item"></i>
            <i class="ant-spin-dot-item"></i>
            <i class="ant-spin-dot-item"></i>
        </span>
        <div class="ant-spin-text">正在加载中... ...</div>
    </div>
</template>

<style scoped>
.ant-spin {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    color: #000000d9;
    font-size: 14px;
    font-variant: tabular-nums;
    line-height: 1.5715;
    list-style: none;
    font-feature-settings: "tnum";
    position: absolute;
    display: none;
    color: #1890ff;
    text-align: center;
    vertical-align: middle;
    opacity: 0;
    transition: transform .3s cubic-bezier(.78,.14,.15,.86)
}
.ant-spin-spinning {
    position: static;
    display: inline-block;
    opacity: 1
}
.ant-spin-container {
    position: relative;
    transition: opacity .3s
}
.ant-spin-container:after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 10;
    display: none;
    width: 100%;
    height: 100%;
    background: #fff;
    opacity: 0;
    transition: all .3s;
    content: "";
    pointer-events: none
}
.ant-spin-blur {
    clear: both;
    opacity: .5;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    pointer-events: none
}
.ant-spin-blur:after {
    opacity: .4;
    pointer-events: auto
}
.ant-spin-tip {
    color: #00000073
}
.ant-spin-dot {
    position: relative;
    display: inline-block;
    font-size: 20px;
    width: 1em;
    height: 1em
}
.ant-spin-dot-item {
    position: absolute;
    display: block;
    width: 9px;
    height: 9px;
    background-color: #1890ff;
    border-radius: 100%;
    transform: scale(.75);
    transform-origin: 50% 50%;
    opacity: .3;
    animation: antSpinMove 1s infinite linear alternate
}
.ant-spin-dot-item:nth-child(1) {
    top: 0;
    left: 0
}
.ant-spin-dot-item:nth-child(2) {
    top: 0;
    right: 0;
    animation-delay: .4s
}
.ant-spin-dot-item:nth-child(3) {
    right: 0;
    bottom: 0;
    animation-delay: .8s
}
.ant-spin-dot-item:nth-child(4) {
    bottom: 0;
    left: 0;
    animation-delay: 1.2s
}
.ant-spin-dot-spin {
    transform: rotate(45deg);
    animation: antRotate 1.2s infinite linear
}
.ant-spin-sm .ant-spin-dot {
    font-size: 14px
}
.ant-spin-sm .ant-spin-dot i {
    width: 6px;
    height: 6px
}
.ant-spin-lg .ant-spin-dot {
    font-size: 32px
}
.ant-spin-lg .ant-spin-dot i {
    width: 14px;
    height: 14px
}
.ant-spin.ant-spin-show-text .ant-spin-text {
    display: block
}
@media all and (-ms-high-contrast: none),(-ms-high-contrast: active) {
    .ant-spin-blur {
        background: #fff;
        opacity: .5
    }
}
.ant-spin-rtl {
    direction: rtl
}
.ant-spin-rtl .ant-spin-dot-spin {
    transform: rotate(-45deg);
    animation-name: antRotateRtl
}
@keyframes antSpinMove {
    to {
        opacity: 1
    }
}
@keyframes antRotate {
    to {
        transform: rotate(405deg)
    }
}
</style>

2. 效果2

vue自定义指令v-loading(vue2和vue3)文章来源地址https://www.toymoban.com/news/detail-422206.html

<template>
    <div class="loading">
        <div class="circle"></div>
        <span>加载中... ...</span>
    </div>
</template>

<style scoped>
.loading {
    color: #1890ff;
    font-size: 12px;

    display: flex;
    flex-direction: column;
    align-items: center;
}
.circle{
    width: 18px;
    height: 18px;
    border: 2px white solid;
    border-left-color: #1890ff;
    border-right-color:#1890ff;
    border-radius: 100%;
    animation: loading1 1s infinite linear;

    margin-bottom: 5px;
}
@keyframes loading1{
    from{transform: rotate(0deg)}to{transform: rotate(360deg)}
}
</style>

到了这里,关于vue自定义指令v-loading(vue2和vue3)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Vue2.0源码学习】指令篇-Vue自定义指令

    在 Vue 中,除了 Vue 本身为我们提供的一些内置指令之外, Vue 还支持用户自定义指令。并且用户有两种定义指令的方式:一种是使用全局API—— Vue.directive 来定义全局指令,这种方式定义的指令会被存放在 Vue.options[\\\'directives\\\'] 中;另一种是在组件内的 directive 选项中定义专为

    2024年02月09日
    浏览(45)
  • vue2 自定义指令,插槽

    1.自定义指令 基本语法(全局、局部注册) 指令的值 v-loading的指令封装 2.插槽 默认插槽 具名插槽 作用域插槽 1.指令介绍 内置指令: v-html、v-if、v-bind、v-on … 这都是Vue给咱们内置的一些指令,可以直接使用 自定义指令:同时Vue也支持让开发者,自己注册一些指令。这些指

    2024年02月11日
    浏览(43)
  • Vue2-收集表单数据、过滤器、内置指令与自定义指令、Vue生命周期

    🥔:我徒越万重山 千帆过 万木自逢春 更多Vue知识请点击——Vue.js 1、不同标签的value属性 若: input type=\\\"text\\\"/ 普通输入框,则v-model收集的是value值,用户输入的就是value值。 若: input type=\\\"radio\\\"/ 单选框,则v-model收集的是value值,且要给标签配置value值。 若: input type=\\\"checkb

    2024年02月13日
    浏览(49)
  • Vue3: 自定义指令

    vue 官方提供了 v-for、v-model、v-if 等常用的内置指令。除此之外vue 还允许开发者自定义指令。 vue 中的自定义指令分为两类,分别是: ⚫ 私有自定义指令 ⚫ 全局自定义指令 在每个 vue 组件中,可以在 directives 节点下声明私有自定义指令。示例代码如下: 在使用自定义指令时

    2024年02月15日
    浏览(33)
  • vue3自定义指令

    在 Vue 3 中,我们可以通过使用 app.directive 方法来定义自定义指令。下面是一个简单的例子: 在上面的例子中,我们定义了一个名为 highlight 的自定义指令,它在元素被挂载时将其背景颜色设置为黄色,并在元素被卸载时将背景颜色重置为空。 在 mounted 和 unmounted 方法中,我们

    2024年01月18日
    浏览(40)
  • vue去掉所有输入框两边空格,封装指令去空格,支持Vue2和Vue3,ElementUI Input去空格

    就是页面很多表单输入框,期望在提交的时候,都要把用户两边的空格去掉 ❌使用 vue 的指令 .trim 去掉空格 中间会输入不了空格, 比如我想输入 你好啊 中国 , 这中间的空格输入不了,只能变成 你好啊中国 ❌在提交的时候使用 trim() 方法去两边空格 需要一个个字段的添加,

    2024年02月14日
    浏览(50)
  • 【学习记录24】vue3自定义指令

    1、html部分  2、js部分 3、实现效果 1、html部分 2、js部分 在components下创建loading文件夹,在loading文件夹里创建directive.js  在main.js中全局注册指令 1、在components下创建loading文件夹,在loading文件夹里创建directive.js 2、在loading文件夹里创建loading.vue 3、在loading文件夹里放入一张G

    2024年01月19日
    浏览(43)
  • vue3自定义指令之防抖

    我们使用 vue 时,有时候需要用到自定义指令,例如一个防抖指令 现在有一个需求,用户在点击某个按钮时,我不希望用户在疯狂点击后,每次点击都会触发事件,像服务器发送请求,这并不是我们预期的,所以我们需要在用户点击是做防抖处理。那么怎么做到方便复用的解

    2024年02月16日
    浏览(37)
  • 前端开发攻略---Vue通过自定义指令实现元素平滑上升的动画效果(可以自定义动画时间、动画效果、动画速度等等)。

    这个指令不是原生自带的,需要手动去书写,但是这辈子只需要编写这一次就好了,后边可以反复利用。 IntersectionObserver 是一个用于监测元素是否进入或离开视口(viewport)的 API。它可以帮助你在页面滚动时或者元素位置改变时进行回调操作,这样你就可以根据元素是否可见

    2024年04月11日
    浏览(53)
  • VUE3实现拖拽功能自定义指令

    1.首先创建一个js文件,命名为drag.js    注意看注释部分,对操作DOM块进行了不同需求的支持     可以只在移动头部时操作整个DOM,或者是否允许DOM元素移出屏幕都能实现 2.在main.js中引入drag.js 3.在你想使用的标签中添加 v-drag 即可实现拖动了  

    2024年02月14日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包