最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3實現全局loading指令的示例詳解

 更新時間:2022年06月02日 09:56:20   作者:Eddie  
這篇文章主要介紹了Vue3實現全局loading指令,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

前言

  • 公司在開發(fā)組件庫的時候,我在封裝loading這個組件時,需要?個全局使?的loading,?插件也可以搞定,但是項?開發(fā)周期不太緊張,所以決定??手寫?個。
  • 寫?個全局的 componnets 也?,但是需要在每個使?的頁?進?導?并且注冊,因為 loading ?到的地?會很多,所以我覺得需要用更優(yōu)雅的方式來實現它。

1.完成loading組件

<template>
  <div class="mask">
    <div class="loader">
      <div>
        <div class="dot"></div>
        <div class="dot"></div>
        <div class="dot"></div>
        <div class="dot"></div>
        <div class="dot"></div>
      </div>
      <div class="tip-text">{{ title }}</div>
    </div>
  </div>
</template>

<script setup>
import { ref, defineExpose } from 'vue'

let title = ref('') // 加載提示文字
 // 更改加載提示文字
 const setTitle = (val) => {
    title.value = val
}
    
 // 暴露出去
 defineExpose({
     title,
     setTitle
 })
}
</script>

<style lang="less" scoped>
.mask {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background-color: rgba(0, 0, 0, 0.8);
  z-index: 99;
  .loader {
    position: absolute;
    top: 50%;
    left: 40%;
    margin-left: 10%;
    transform: translate3d(-50%, -50%, 0);
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  .tip-text {
    color: #3793ff;
    padding-top: 10px;
  }
  .dot {
    width: 18px;
    height: 18px;
    border-radius: 100%;
    display: inline-block;
    animation: slide 1s infinite;
  }
  .dot:nth-child(1) {
    animation-delay: 0.1s;
    background: #1fbfff;
  }
  .dot:nth-child(2) {
    animation-delay: 0.2s;
    background: #2ea4ff;
  }
  .dot:nth-child(3) {
    animation-delay: 0.3s;
    background: #3793ff;
  }
  .dot:nth-child(4) {
    animation-delay: 0.4s;
    background: #3b89ff;
  }
  .dot:nth-child(5) {
    animation-delay: 0.5s;
    background: #4577ff;
  }
}

@-moz-keyframes slide {
  0% {
    transform: scale(1);
  }
  50% {
    opacity: 0.3;
    transform: scale(2);
  }
  100% {
    transform: scale(1);
  }
}
@-webkit-keyframes slide {
  0% {
    transform: scale(1);
  }
  50% {
    opacity: 0.3;
    transform: scale(2);
  }
  100% {
    transform: scale(1);
  }
}
@-o-keyframes slide {
  0% {
    transform: scale(1);
  }
  50% {
    opacity: 0.3;
    transform: scale(2);
  }
  100% {
    transform: scale(1);
  }
}
@keyframes slide {
  0% {
    transform: scale(1);
  }
  50% {
    opacity: 0.3;
    transform: scale(2);
  }
  100% {
    transform: scale(1);
  }
}
</style>

2.新建?個loading.js?件,?來寫loading的?定義指令邏輯

const loadingDirective = { 
    mounted(el,binding) { 
    },
    updated(el,binding) {
    },
}
return loadingDirective  // 導出

在創(chuàng)建的 loadingDirective 對象中,寫?兩個鉤?函數,因為我們希望在這兩個生命周期函數,對它進?操作。

2.1 創(chuàng)建這個組件對應的 DOM

  • 新建?個新的vue實例,再對它進??個動態(tài)的掛載,掛載之后我們就可以拿到這個 DOM 的實例了

具體實現看如下代碼塊

import { createApp } from 'vue' // 導? createApp ?法
import Loading from './loading' // 導?我們寫好的 loading 組件
const loadingDirective = {
    mounted(el, binding) {
        // 創(chuàng)建app對象跟組件為我們寫好的 loading 組件
        const app = createApp(Loading)
        // 動態(tài)創(chuàng)建?個div節(jié)點,將app掛載在div上
        // 我們的 loading 組件將替換此 div 標簽的 innerHTML
        const instance = app.mount(document.createElement('div'))
    },
    updated(el, binding) {},
}
return loadingDirective  // 導出

2.2 在 loading.js 文件中新增兩個方法,分別是插入節(jié)點和移除節(jié)點。

import { createApp } from 'vue' // 導? createApp ?法
import Loading from './loading' // 導?我們寫好的 loading 組件
const loadingDirective = {
    mounted(el, binding) {
        // 創(chuàng)建app對象跟組件為我們寫好的 loading 組件
        const app = createApp(Loading)
        
        // 動態(tài)創(chuàng)建?個div節(jié)點,將app掛載在div上
        // 我們的 loading 組件將替換此 div 標簽的 innerHTML
        const instance = app.mount(document.createElement('div'))
        
        // 因為在updated也需要?到 instance 所以將 instance 添加在 el 上
        // 在 updated中 通過el.instance 可訪問到
        el.instance = instance
        
        // v-loading傳過來的值儲存在 binding.value 中
        if (binding.value) {
            append(el)
        }
    },
    updated(el, binding) {
       remove(el)
    },
}
return loadingDirective  // 導出

// 插入節(jié)點
function append(el) {
    // 向el節(jié)點插?動態(tài)創(chuàng)建的 div 節(jié)點,內容就是我們的 loading 組件
    el.appendChild(el.instance.$el)  
}
// 移除節(jié)點
function remove(el) {
    // 移除動態(tài)創(chuàng)建的 div 節(jié)點
    el.removeChild(el.instance.$el)
}

2.3 完善 updated 周期函數

在?開始的時候將節(jié)點插?,在 v-loading 的值發(fā)?改變時候觸發(fā) updated 我們將節(jié)點移除, 但是這樣寫是不合適的,我們需要完善?下在 updated 中的操作。

updated (el, binding) {
    // 如果value的值有改變,那么我們去判斷進?操作
    if (binding.value !== binding.oldValue) {
      // 三元表達式 true 插入 false 移除
      binding.value ? append(el) : remove(el)
    }

基本的指令已經完成的差不多了。

2.4 解決存在的三個問題

  • 位置定位的問題,如果所在掛載的 DOM 元素有定位屬性,那么沒有問題,但是所在掛載的 DOM 元素沒有定位的時候,那么它??的絕對定位,就有可能出現問題。
  • 頁面滾動的問題,如果出現 loading 效果, 遮罩層后面的頁面會發(fā)生滾動,滾動遮罩層時會造成底部頁面跟著一塊滾動。
  • 加載文字需求,我們還可以加入?段?字進?展?,不同的地?需要等待時的?字會有不同。

2.4.1 ?先來解決第?個和第二個問題

  • 在插?節(jié)點的時候去判斷掛載的節(jié)點有沒有定位,如果沒有則為其添加相對定位。
  • 在插?節(jié)點的時候為其添加禁止/隱藏滾動。
  • 在移除節(jié)點的時候移除類名。
const relative = 'g-relative' // g-relative 全局相對定位樣式名稱
const hidden = 'g-hidden' // g-hidden 全局禁止/隱藏滾動樣式名稱
// 插入節(jié)點
function append(el) {
const style = getComputedStyle(el)
    el.classList.add(hidden) // 添加類名
  if (['absolute', 'relative', 'fixed'].indexOf(style.position) === -1) {
    el.classList.add(relative) // 添加類名
  }
    // 向el節(jié)點插?動態(tài)創(chuàng)建的 div 節(jié)點,內容就是我們的 loading 組件
    el.appendChild(el.instance.$el)
}
// 移除節(jié)點
function remove(el) {
    // 移除動態(tài)創(chuàng)建的 div 節(jié)點
    el.removeChild(el.instance.$el)
    el.classList.remove(relative) // 移除類名
    el.classList.remove(hidden) // 移除類名
}

g-relative g-hidden 是我在全局css?件中寫的樣式

.g-relative {
    position: relative;
}
.g-hidden {
    overflow: hidden;
}

2.4.2 最后解決第三個問題,動態(tài)顯示加載文字。

在?的地?使? :[] 的語法

<template>
  <div class="demo" v-loading:[title]="loading"></div>
</template>
<script setup>
import { ref } from 'vue'

const title = ref('拼命加載中...')
const loading = ref(true)
}
</script>
  • 傳?title之后需要進?接收,并插?titleloading
  • 通過binding.arg可接收到 :[] 傳來的值
import { createApp } from 'vue' // 導? createApp ?法
import Loading from './loading' // 導?我們寫好的 loading 組件
const loadingDirective = {
    mounted(el, binding) {
        // 創(chuàng)建app對象跟組件為我們寫好的 loading 組件
        const app = createApp(Loading)
        
        // 動態(tài)創(chuàng)建?個div節(jié)點,將app掛載在div上
        // 我們的 loading 組件將替換此 div 標簽的 innerHTML
        const instance = app.mount(document.createElement('div'))
        
        // 因為在updated也需要?到 instance 所以將 instance 添加在 el 上
        // 在 updated中 通過el.instance 可訪問到
        el.instance = instance
        
        // v-loading傳過來的值儲存在 binding.value 中
        if (binding.value) {
            append(el)
        }
        
        // 在此判斷是否有title值
        if (binding.arg !== 'undefined') {
         // setTitle 使我們在loading組件中定義的?法
          el.instance.setTitle(binding.arg)  
        }
    },
    updated (el, binding) {
        // 在此判斷是否有title值
        if (binding.arg !== 'undefined') {
         // setTitle 使我們在loading組件中定義的?法
          el.instance.setTitle(binding.arg)  
        }
        
        // 如果value的值有改變,那么我們去判斷進?操作
        if (binding.value !== binding.oldValue) {
          // 三元表達式 true 插入 false 移除
          binding.value ? append(el) : remove(el)
        }
     }
}
return loadingDirective  // 導出

const relative = 'g-relative' // g-relative 全局相對定位樣式名稱
const hidden = 'g-hidden' // g-hidden 全局禁止/隱藏滾動樣式名稱
// 插入節(jié)點
function append(el) {
const style = getComputedStyle(el)
    el.classList.add(hidden) // 添加類名
  if (['absolute', 'relative', 'fixed'].indexOf(style.position) === -1) {
    el.classList.add(relative) // 添加類名
  }
    // 向el節(jié)點插?動態(tài)創(chuàng)建的 div 節(jié)點,內容就是我們的 loading 組件
    el.appendChild(el.instance.$el)
}
// 移除節(jié)點
function remove(el) {
    // 移除動態(tài)創(chuàng)建的 div 節(jié)點
    el.removeChild(el.instance.$el)
    el.classList.remove(relative) // 移除類名
    el.classList.remove(hidden) // 移除類名
}

3.在main.js文件中引?注冊

想要在全局使?這個自定義指令,那么我們需要在 main.js 文件中去引?注冊。

import { createApp } from 'vue'
import App from './App.vue'
import '@/assets/scss/global.css' // 引入全局樣式文件
import loadingDirective from '@/views/loading/directive' //引?loading?定義指令
createApp(App)
  .directive('loading', loadingDirective)  // 全局注冊loading指令
  .mount('#app')

4.在頁面中使用自定義loading指令

onMounted 的時候,判斷loading 是否顯?,在做判斷之前,先來看看我們在寫好 loading ?定義指令之后,該如何在頁面中使用它。

<template>
  <div v-loading="loading"></div> // 只需在節(jié)點上寫上 v-loading='loading' 即可,后邊的loading是?個值
</template>
<script setup>
import { ref, onMounted } from 'vue'

const loading = ref(true)  // 默認讓 loading 值為true 傳給loading組件

onMounted(() => {
  // 定時器模擬數據加載完成之后更改 loading 狀態(tài)
  setTimenout(() => {    
     loading.value = false    
  }, 3000)
})
</script>

此時我們在 loading 組件中就可以接收到傳?的值,我們根據值來判斷是否顯? loading 組件

到此這篇關于Vue3實現全局loading指令的文章就介紹到這了,更多相關Vue3 全局loading指令內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Vue監(jiān)聽屬性和計算屬性

    Vue監(jiān)聽屬性和計算屬性

    這篇文章主要介紹了Vue監(jiān)聽屬性和計算屬性,基本用法添加watch屬性,值為一個對象。對象的屬性名就是要監(jiān)視的數據,屬性值為回調函數,每當這個屬性名對應的值發(fā)生變化,就會觸發(fā)該回調函數執(zhí)行,下面來看詳細內容,需要的朋友也可以參考一下
    2021-12-12
  • 使用vue3重構拼圖游戲的實現示例

    使用vue3重構拼圖游戲的實現示例

    這篇文章主要介紹了使用vue3重構拼圖游戲的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • VUE + UEditor 單圖片跨域上傳功能的實現方法

    VUE + UEditor 單圖片跨域上傳功能的實現方法

    這篇文章主要介紹了VUE + UEditor 單圖片跨域上傳功能的實現方法,需要的朋友參考下
    2018-02-02
  • 在vue或H5中如何使用復制粘貼功能

    在vue或H5中如何使用復制粘貼功能

    這篇文章主要介紹了在vue或H5中如何使用復制粘貼功能,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue3中使用keepAlive緩存路由組件不生效的問題解決

    vue3中使用keepAlive緩存路由組件不生效的問題解決

    這篇文章主要介紹了vue3中使用keepAlive緩存路由組件不生效的問題解決,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-06-06
  • 在Vue?3中使用OpenLayers加載GPX數據并顯示圖形效果

    在Vue?3中使用OpenLayers加載GPX數據并顯示圖形效果

    本文介紹了如何在Vue 3中使用OpenLayers加載GPX格式的數據并在地圖上顯示圖形,通過使用OpenLayers的GPX解析器,我們能夠輕松地處理和展示來自GPS設備的地理數據,需要的朋友可以參考下
    2024-12-12
  • 關于vue中媒體查詢不起效的原因總結

    關于vue中媒體查詢不起效的原因總結

    這篇文章主要介紹了關于vue中媒體查詢不起效的原因總結,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Vue+Bootstrap收藏(點贊)功能邏輯與具體實現

    Vue+Bootstrap收藏(點贊)功能邏輯與具體實現

    這篇文章主要為大家詳細介紹了Vue+Bootstrap收藏(點贊)功能邏輯與具體實現,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • vue路由跳轉時判斷用戶是否登錄功能的實現

    vue路由跳轉時判斷用戶是否登錄功能的實現

    下面小編就為大家?guī)硪黄獀ue路由跳轉時判斷用戶是否登錄功能的實現。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • axios?發(fā)?post?請求,后端接收不到參數的完美解決方案

    axios?發(fā)?post?請求,后端接收不到參數的完美解決方案

    這篇文章主要介紹了axios?發(fā)?post?請求,后端接收不到參數的解決方案,場景很簡單,就是一個正常 axios post 請求,本文給大家分享問題原因分析及解決方案需要的朋友可以參考下
    2022-12-12

最新評論

博客| 揭阳市| 钦州市| 正宁县| 大埔区| 中山市| 池州市| 龙游县| 德州市| 阳江市| 泰和县| 攀枝花市| 濮阳县| 旅游| 获嘉县| 噶尔县| 镶黄旗| 南汇区| 临猗县| 通化市| 邢台市| 桦南县| 井冈山市| 余庆县| 修文县| 汝城县| 平顶山市| 阳春市| 青铜峡市| 宾阳县| 霍州市| 中牟县| 托里县| 宁阳县| 辛集市| 丽江市| 隆昌县| 丰镇市| 安吉县| 祁阳县| 沙田区|