vue自定義加載指令最新詳解
前言
用過element-ui
的都應該知道,裡面有一個loading
組件,有兩種調用方法:指令和服務。但是隻有一種加載效果,為瞭豐富加載效果和方便使用,於是寫瞭一個自定義loading
指令。
創建加載組件
首先,需要創建loading
組件,展示需要的加載效果,因人而異,不再贅述。
創建指令
指令文件
首先,創建一個js
文件用於書寫自定義指令,在這個文件中導入Vue
和loading
組件:
import Vue from 'vue' import loading from './loading.vue'
創建構造器
主要是使用Vue.extend
構造器,可以簡單的理解為傳入一個組件作為參數,然後返回該組件的類,可以使用這個類new
出實例。
// loading組件作為參數傳入 const loadingConstructor = Vue.extend(loading)
書寫指令
在此之前,設定好指令的參數,在本人的項目中,參數有兩種方式:1.傳入一個佈爾值,代表是否開啟加載;2.傳入一個對象,對象中包含是否開啟遮罩、提示文字、加載背景顏色等屬性,方便開發時,高度自定義laoding
。
指令的觸發主要是在update
中,該屬性可接收一個函數,每次指令的參數改變時都會觸發該函數,就是在這裡判斷開啟或者關閉加載效果。 整體代碼如下,附有詳細註釋:
const loadingDirective = Vue => { Vue.directive('custLoading', { /** * binding: * 1.可傳單個參數,為佈爾值; * 2.也可用json傳多個參數{ loading, tip, background } * 2.1 loading { boolean } 是否開啟遮罩 * 2.2 tip { string } 提示文字 * 2.3 background { string } 加載背景顏色 * */ // update: 參數變化時觸發 update: function (el, binding, vnode) { const value = binding.value let backup = {} // 判斷參數類型,將參數都轉換為對象,方便後續統一處理 typeof value === 'boolean' ? (backup.loading = value) : (backup = value || {}) // 取出所有的參數 const { loading, tip, background } = backup // 根據loading參數判斷開啟或者關閉加載效果,開啟和關閉函數後續會講到 loading ? createLoading(el, tip, background) : close(el?.customLoadingInstance?.$el) }, // unbid: 指令卸載時觸發 unbind: function (el, binding) { const { loading } = binding.value || {} // 如果還在展示加載特效,則關閉 loading && close(el?.customLoadingInstance?.$el) } }) } export default loadingDirective
開啟函數
在上面的指令中,當開啟的參數為true
時,回會調用一個createLoading
函數用於將加載效果加入到指令掛載的元素上,具體思路如下:1.
在調用時,我們傳入瞭三個參數給它,分別是掛載有自定義加載指令的元素、加載時的提示、加載背景顏色,詳細可見上面的指令代碼。2.
在執行之前,還需要進行判斷當前的Vue
實例是否運行在服務器上,如果是,此時不需要將加載效果展示出來;或者該元素之前是否已經帶有加載特效,如果是的話,沒必要在開啟一次,不然到時會出現多層加載效果,既多餘,又讓頁面顯得混亂。3.
判斷需要使用加載效果的元素是否還存在,不存在,則掛載到#main
或者document.body
上。4.
判斷元素上是否存在定位或者其他條件,在本人的項目中,使用絕對定位來使加載效果鋪滿元素,因此需要進行判斷,如果沒有定位,則加上relative
。5.
使用loadingConstructor
,創建loading
實例,將實例作為子元素通過appendChild
,放進需要展示的元素中,就可以展示出來;同時,在展示的元素上增加一個屬性customLoadingInstance
,用於記錄當前的loading
實例,方便後續的銷毀。
整體代碼如下:
const createLoading = (target, tip= '加載中,請稍候...', background) => { // 判斷是否允許開啟加載特效 if (Vue.prototype.$isServer || target?.customLoadingInstance) return const mainEL = document.querySelector('#main') // 判斷展示加載效果的元素是否存在 const parentNode = target || mainEL || document.body // 判斷父級是否存在定位,沒有則添加定位 const position = getComputedStyle(parentNode)?.position (!position || position === 'static') && (parentNode.style.position = 'relative') // 創建loading實例 const instance = new loadingConstructor({ el: document.createElement('div'), data: { background, tip, parentNodeWidth: parentNode.clientWidth, isShow: true } }) // 註意:loading實例是一個Vue組件對象,真正的DOM放在實例的$el屬性上 parentNode.appendChild(instance.$el) parentNode.customLoadingInstance = instance return instance }
關閉函數
有開啟就得有結束,當開啟的參數為false
時,關閉加載效果。該函數接收loading
實例的$el
,其實就是加載效果的DOM
元素,思路如下:1.
為瞭使加載組件看起來是逐漸消失的,不得在第一時間將加載效果的DOM
元素刪除,而是給它添加一個逐漸消失的動畫,通過一個class
設定。2.
設定動畫消失時間,由loading
組件內部實現在規定時間內,將整個加載效果執行完成或者淡出頁面。也可省略此步驟,直接就將其移除。 之所以加入這個效果,是為瞭用戶視覺上感受更好。3.
創建定時器,用於在加載效果消失時,刪除加載效果的DOM
元素。同2,也可直接移除。
const close = (target) => { if (!target) return // 添加逐漸消失的class target.className += ' custom-loading-disappear' // 獲取loading實例 const instance = target?.parentNode?.customLoadingInstance // 設定消失時間。 instance?.$data?.dur && (instance.$data.dur = 0.8) // 設定定時器,用於在加載效果消失時,刪除加載效果的`DOM`元素。 let timer = setTimeout(() => { if (target && target.parentNode) { // 將customLoadingInstance 屬性置為null,才不會幹擾下一次開啟 target.parentNode.customLoadingInstance = null // 將加載效果的DOM元素移除 target.parentNode.removeChild(target) } clearTimeout(timer) timer = null }, 1100) }
到此這篇關於vue自定義加載指令的文章就介紹到這瞭,更多相關vue自定義加載指令內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!