欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3實(shí)現(xiàn)全局loading指令的示例詳解

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

前言

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

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  // 導(dǎo)出

在創(chuàng)建的 loadingDirective 對象中,寫?兩個鉤?函數(shù),因?yàn)槲覀兿M谶@兩個生命周期函數(shù),對它進(jìn)?操作。

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

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

具體實(shí)現(xiàn)看如下代碼塊

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

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

import { createApp } from 'vue' // 導(dǎo)? createApp ?法
import Loading from './loading' // 導(dǎo)?我們寫好的 loading 組件
const loadingDirective = {
    mounted(el, binding) {
        // 創(chuàng)建app對象跟組件為我們寫好的 loading 組件
        const app = createApp(Loading)
        
        // 動態(tài)創(chuàng)建?個div節(jié)點(diǎn),將app掛載在div上
        // 我們的 loading 組件將替換此 div 標(biāo)簽的 innerHTML
        const instance = app.mount(document.createElement('div'))
        
        // 因?yàn)樵趗pdated也需要?到 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  // 導(dǎo)出

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

2.3 完善 updated 周期函數(shù)

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

updated (el, binding) {
    // 如果value的值有改變,那么我們?nèi)ヅ袛噙M(jìn)?操作
    if (binding.value !== binding.oldValue) {
      // 三元表達(dá)式 true 插入 false 移除
      binding.value ? append(el) : remove(el)
    }

基本的指令已經(jīng)完成的差不多了。

2.4 解決存在的三個問題

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

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

  • 在插?節(jié)點(diǎn)的時(shí)候去判斷掛載的節(jié)點(diǎn)有沒有定位,如果沒有則為其添加相對定位。
  • 在插?節(jié)點(diǎn)的時(shí)候?yàn)槠涮砑咏?隱藏滾動。
  • 在移除節(jié)點(diǎn)的時(shí)候移除類名。
const relative = 'g-relative' // g-relative 全局相對定位樣式名稱
const hidden = 'g-hidden' // g-hidden 全局禁止/隱藏滾動樣式名稱
// 插入節(jié)點(diǎn)
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é)點(diǎn)插?動態(tài)創(chuàng)建的 div 節(jié)點(diǎn),內(nèi)容就是我們的 loading 組件
    el.appendChild(el.instance.$el)
}
// 移除節(jié)點(diǎn)
function remove(el) {
    // 移除動態(tài)創(chuàng)建的 div 節(jié)點(diǎn)
    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之后需要進(jìn)?接收,并插?titleloading
  • 通過binding.arg可接收到 :[] 傳來的值
import { createApp } from 'vue' // 導(dǎo)? createApp ?法
import Loading from './loading' // 導(dǎo)?我們寫好的 loading 組件
const loadingDirective = {
    mounted(el, binding) {
        // 創(chuàng)建app對象跟組件為我們寫好的 loading 組件
        const app = createApp(Loading)
        
        // 動態(tài)創(chuàng)建?個div節(jié)點(diǎn),將app掛載在div上
        // 我們的 loading 組件將替換此 div 標(biāo)簽的 innerHTML
        const instance = app.mount(document.createElement('div'))
        
        // 因?yàn)樵趗pdated也需要?到 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的值有改變,那么我們?nèi)ヅ袛噙M(jìn)?操作
        if (binding.value !== binding.oldValue) {
          // 三元表達(dá)式 true 插入 false 移除
          binding.value ? append(el) : remove(el)
        }
     }
}
return loadingDirective  // 導(dǎo)出

const relative = 'g-relative' // g-relative 全局相對定位樣式名稱
const hidden = 'g-hidden' // g-hidden 全局禁止/隱藏滾動樣式名稱
// 插入節(jié)點(diǎn)
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é)點(diǎn)插?動態(tài)創(chuàng)建的 div 節(jié)點(diǎn),內(nèi)容就是我們的 loading 組件
    el.appendChild(el.instance.$el)
}
// 移除節(jié)點(diǎn)
function remove(el) {
    // 移除動態(tài)創(chuàng)建的 div 節(jié)點(diǎn)
    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 的時(shí)候,判斷loading 是否顯?,在做判斷之前,先來看看我們在寫好 loading ?定義指令之后,該如何在頁面中使用它。

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

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

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

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

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

相關(guān)文章

  • Vue中的echarts圖表如何實(shí)現(xiàn)loading效果

    Vue中的echarts圖表如何實(shí)現(xiàn)loading效果

    這篇文章主要介紹了Vue中的echarts圖表如何實(shí)現(xiàn)loading效果,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue瀏覽器返回監(jiān)聽的具體步驟

    vue瀏覽器返回監(jiān)聽的具體步驟

    這篇文章主要給大家介紹了關(guān)于vue瀏覽器返回監(jiān)聽的具體步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 前端Vue3引入高德地圖并展示行駛軌跡動畫的步驟

    前端Vue3引入高德地圖并展示行駛軌跡動畫的步驟

    最近在Vue項(xiàng)目中引入高德地圖,實(shí)現(xiàn)地圖展示與交互的方法和技術(shù),這里跟大家分享下,這篇文章主要給大家介紹了關(guān)于前端Vue3引入高德地圖并展示行駛軌跡動畫的相關(guān)資料,需要的朋友可以參考下
    2024-09-09
  • 學(xué)習(xí)Vue組件實(shí)例

    學(xué)習(xí)Vue組件實(shí)例

    本篇文章給大家分享了Vue實(shí)例的相關(guān)內(nèi)容以及重要知識點(diǎn),對此有興趣的朋友可以跟著學(xué)習(xí)參考下。
    2018-04-04
  • 使用@tap.stop阻止事件繼續(xù)傳播

    使用@tap.stop阻止事件繼續(xù)傳播

    這篇文章主要介紹了使用@tap.stop阻止事件繼續(xù)傳播,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Vue?3?表格時(shí)間監(jiān)控與動態(tài)后端請求觸發(fā)詳解?附Demo展示

    Vue?3?表格時(shí)間監(jiān)控與動態(tài)后端請求觸發(fā)詳解?附Demo展示

    在Vue3中,使用el-table組件渲染表格數(shù)據(jù),通過el-table-column指定內(nèi)容,時(shí)間點(diǎn)需前端校準(zhǔn),用getTime()比較,到達(dá)時(shí)觸發(fā)操作,異步API請求可用async/await處理,setInterval實(shí)現(xiàn)定時(shí)監(jiān)控,配合條件判斷防止重復(fù)請求
    2024-09-09
  • Vue3.x如何設(shè)置瀏覽器動態(tài)Title方法

    Vue3.x如何設(shè)置瀏覽器動態(tài)Title方法

    這篇文章主要介紹了Vue3.x如何設(shè)置瀏覽器動態(tài)Title方法,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue: WebStorm設(shè)置快速編譯運(yùn)行的方法

    vue: WebStorm設(shè)置快速編譯運(yùn)行的方法

    今天小編就為大家分享一篇vue: WebStorm設(shè)置快速編譯運(yùn)行的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • vue2.0+vue-router構(gòu)建一個簡單的列表頁的示例代碼

    vue2.0+vue-router構(gòu)建一個簡單的列表頁的示例代碼

    這篇文章主要介紹了vue2.0+vue-router構(gòu)建一個簡單的列表頁的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-02-02
  • Vue路由跳轉(zhuǎn)的4種方式小結(jié)

    Vue路由跳轉(zhuǎn)的4種方式小結(jié)

    本文主要介紹了Vue路由跳轉(zhuǎn)的4種方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06

最新評論