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

如何實現vue加載指令 v-loading

 更新時間:2024年01月15日 10:53:59   作者:劫辭  
在日常的開發(fā)中,加載效果是非常常見的,但是怎么才能方便的使用,本文介紹如何實現vue加載指令 v-loading,感興趣的朋友一起看看吧

本文不會詳細的說明 vue 中指令這些知識點,如果存在疑問,請自行查閱文檔或者其他資料

為什么使用指令實現

  • 在日常的開發(fā)中,加載效果是非常常見的,但是怎么才能方便的使用,那就還是值得思考一番的,
  • 比如在 vue 中,最簡單的方式就是封裝為一個組件了,但是如果封裝為組件的話,在不想注冊為全局組件的時候,每次都需要引入、注冊、使用;如果注冊為全局組件,你也往往需要分析結構在合適的位置插入組件,貌似使用起來都會麻煩一點,loading 這種使用頻率高的效果,使用一次麻煩一點,使用100次就會覺得更加麻煩
  • 而使用指令只需要在需要的位置像使用屬性一樣即可;封裝可以麻煩,但是使用越簡單越好

具體實現

封裝準備

1.首先需要一個 js 文件,因為指令實際上就是一個對象,通過在不同的鉤子函數中執(zhí)行對應的邏輯,在本文中,需要使用的鉤子函數是 inserted 和 update,因此可以寫一個基礎的結構,如下:

export default {
    inserted(el, binding){
    },
    update(el, binding){
    }
}

2.然后將這個指令在入口文件 main.js 內進行全局注冊,如下:

import vLoading from '你封裝指令js文件的路徑'
// 注冊指令
Vue.directive('jc-loading', vLoading)

3.創(chuàng)建一個 vue 文件來使用這個指令,如下:

<template>
	<div class="container">
		<button
			style="margin-bottom: 20px"
			@click="handleClick">
			開關
		</button>
		<div
			class="box"
			v-jcLoading="isLoading">
			Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero, temporibus veniam! Totam temporibus ipsam, atque
			amet aliquid corporis molestiae, perspiciatis asperiores doloremque enim explicabo aperiam. Vel doloremque
			voluptatibus incidunt quae suscipit cupiditate. Obcaecati sunt, consectetur voluptas sequi aliquam omnis, rem non
			molestiae assumenda illum quasi excepturi error voluptatibus pariatur nulla.
		</div>
	</div>
</template>
<script>
export default {
	data() {
		return {
			isLoading: false
		}
	},
	methods: {
		handleClick() {
			this.isLoading = !this.isLoading
		}
	}
}
</script>
<style lang="less" scoped>
.container {
	width: 100vw;
	height: 100vh;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	.box {
		width: 500px;
		height: 300px;
		padding: 20px;
		border: 1px solid #999;
		color: #f40;
	}
}
</style>

4.查看一下指令內的輸出語句是否正常執(zhí)行,如圖:

5.正常進行了打印,現在我們進行正式的編寫

實現 loading 效果

1.實現這一步其實也非常的簡單,找一個你覺得好看或者合適的加載效果,按照正常的 html+css+js 進行實現就好,當你實現好之后,需要做的就是使用 js 進行動態(tài)的創(chuàng)建這些元素,所以我們需要有一個函數幫助我們完成這一步,如下:

// 導入模塊化的 less 文件
import styles from './loading.module.less'
// 創(chuàng)建 loading 元素
function createLoading() {
	// 創(chuàng)建 load 遮罩
	const loadingMask = document.createElement('div')
	loadingMask.dataset.role = 'jc-loading'
	loadingMask.classList.add(styles['jc-loading-mask'])
	// 創(chuàng)建 loading 旋轉容器元素
	const loadingSpinner = document.createElement('div')
	loadingSpinner.classList.add(styles['jc-loading-spinner'])
	loadingMask.appendChild(loadingSpinner)
	// 創(chuàng)建文本片段
	const fragment = document.createDocumentFragment()
	// 創(chuàng)建子元素進行旋轉縮放
	for (let i = 0; i < 12; i++) {
		const div = document.createElement('div')
		div.style = `--i:${i}`
		div.classList.add(styles['jc-loading-spinner__circle'])
		fragment.appendChild(div)
	}
	loadingSpinner.appendChild(fragment)
	return loadingMask
}

2.代碼還是非常簡單的,具體取決于你本身實現的 loading 效果,我這個是一個比較簡單的動效,上面這個地方如果有疑問那應該就是證據導入語句,在 vue 中,如果希望一個 less 文件作為一個模塊導入和使用,需要將文件命名改為 文件名.module.less 這種格式,即文件后綴為 .module.less,我們在 inserted 鉤子函數中打印一下這個導入的 styles,如下:

export default {
    inserted(el, binding){
        console.log(styles)
    },
    update(el, binding){
    }
}

3.結果如圖:

4.k 為 less 文件中開發(fā)時書寫的類名,而后面的 v 表示實際的類名,本案例中 less 文件代碼如下:

.jc-loading-mask {
	position: absolute;
	inset: 0;
	background-color: rgba(0, 0, 0, 0.7);
}
.jc-loading-spinner {
	position: absolute;
	left: calc(50% - 25px);
	top: calc(50% - 25px);
	width: 50px;
	height: 50px;
	animation: sp 4s linear infinite;
}
.jc-loading-spinner__circle {
	position: absolute;
	top: 0;
	left: calc(50% - 3px);
	width: 6px;
	height: 6px;
	transform: rotate(calc(var(--i) * (360deg / 12)));
	transform-origin: center 25px;
}
.jc-loading-spinner__circle::before {
	content: '';
	inset: 0;
	border-radius: 50%;
	position: absolute;
	background-color: #ff6348;
	animation: zoom 2.5s linear infinite;
	animation-delay: calc(var(--i) * 0.2s);
}
@keyframes sp {
	to {
		transform: rotate(360deg);
	}
}
@keyframes zoom {
	0% {
		transform: scale(1.2);
	}
	50% {
		transform: scale(0.5);
	}
	100% {
		transform: scale(1.2);
	}
}

5.這些 css 樣式我就不再贅述了,先不進行其他邏輯判斷,只展示到頁面上,看看效果,代碼如下:

export default {
    inserted(el, binding){
      	el.appendChild(createLoading())
    },
    update(el, binding){
    }
}

6.效果如圖:

7.其實也不難對吧,這個效果你可以根據自己的需求來進行更換,但是實現方法都是可以套用的

loading 顯示與隱藏

1.把這個需求梳理清楚之后,后面的就呼之欲出了,什么時候顯示,必然是指令上的值為 true 的時候,隱藏則相反,這是一個先決條件

2.在這個條件之后呢?還需要考慮什么呢?是不是需要創(chuàng)建這個 loading 效果的元素啊,當指令的值為 true 且不存在當前的 loading 元素的時候,才需要創(chuàng)建,而指令的值為 false ,則是當前的 loading 元素存在的話,就需要移除啊

3.基于上面的條件,我們需要一個輔助函數,來幫助我們查找當前 loading 效果的元素是否存在,如下:

function getLoading(container) {
	return container.querySelector(`[data-role="jc-loading"]`)
}

4.所以我們在 inserted 鉤子函數中,應該進行判斷,當指令的值為 true 且元素不存在時,就創(chuàng)建元素并添加,如下:

inserted(el, binding){
	// 如果為 true 且不存在加載元素就創(chuàng)建元素添加加載效果
	if (!getLoading(el)) {
		const loading = createLoading()
		el.appendChild(loading)
	}
}

5.而 update 函數中的代碼是不是也可以寫出來了,進行條件判斷來執(zhí)行邏輯,而且不難發(fā)現其實這個條件與 inserted 中的條件是重合的,所以我們可以封裝為一個函數,如下:

// 開啟加載效果
function openLoading(el, binding) {
	// 如果為 false 且存在加載元素就移除加載元素
	if (!binding.value) {
		const dom = getLoading(el)
		dom && dom.remove()
	} else {
		// 如果為 true 且不存在加載元素就創(chuàng)建元素添加加載效果
		if (!getLoading(el)) {
			const loading = createLoading()
			el.appendChild(loading)
		}
	}
}

6.當然,還需要考慮當前顯示加載元素的 dom 是不是存在相對定位,如果不存在則改為相對定位,最后指令對象的實際代碼如下:

export default {
    inserted(el, binding){
        // 檢測綁定的元素的 position 屬性是否為 static
		if (window.getComputedStyle(el).position === 'static') {
			// 如果是則改為相對定位
			el.style.position = 'relative'
		}
      	openLoading(el, binding)
    },
    update(el, binding){
        openLoading(el, binding)
    }
}

7.我們看一下實際的效果,如圖:

使用修飾符擴展

1.通過 modifiers(修飾符) 進行一個擴展,當指令了添加了修飾符 body 的時候,loading 就會插入到 body 里面,填充 body,所以我們還需要進行一些額外的判斷,如下:

function getContainer(el, binding) {
	return binding.modifiers.body ? document.body : el
}
export default {
	inserted(el, binding) {
		if (window.getComputedStyle(el).position === 'static') {
			el.style.position = 'relative'
		}
		openLoading(getContainer(el, binding), binding)
	},
	update(el, binding) {
		openLoading(getContainer(el, binding), binding)
	}
}

2.此時在組件中使用添加修飾符 body 即可,如下:

<!-- 添加修飾符.body -->
<div class="box" v-jcLoading.body="isLoading">
...
</div>

3.查看效果,如圖:

4.元素實際插入的位置,如圖:

完整代碼與結語

1.現在已經具備了一個 loading 指令基本的效果,如果還需要進行其他擴展,比如傳遞給 loading 指令的值不是一個單純的布爾值,而是一個對象,如下:

{ loading:true, color: 'blue', text: '拼命加載中...' ... }

2.通過這些配置來增強指令的效果,有興趣的可以自己試試

3.完整指令代碼:

import styles from './loading.module.less'
function getLoading(container) {
	return container.querySelector(`[data-role="jc-loading"]`)
}
function createLoading() {
	const loadingMask = document.createElement('div')
	loadingMask.dataset.role = 'jc-loading'
	loadingMask.classList.add(styles['jc-loading-mask'])
	const loadingSpinner = document.createElement('div')
	loadingSpinner.classList.add(styles['jc-loading-spinner'])
	loadingMask.appendChild(loadingSpinner)
	const fragment = document.createDocumentFragment()
	for (let i = 0; i < 12; i++) {
		const div = document.createElement('div')
		div.style = `--i:${i}`
		div.classList.add(styles['jc-loading-spinner__circle'])
		fragment.appendChild(div)
	}
	loadingSpinner.appendChild(fragment)
	return loadingMask
}
function openLoading(el, binding) {
	if (!binding.value) {
		const dom = getLoading(el)
		dom && dom.remove()
	} else {
		if (!getLoading(el)) {
			const loading = createLoading()
			el.appendChild(loading)
		}
	}
}
function getContainer(el, binding) {
	return binding.modifiers.body ? document.body : el
}
export default {
	inserted(el, binding) {
		if (window.getComputedStyle(el).position === 'static') {
			el.style.position = 'relative'
		}
		openLoading(getContainer(el, binding), binding)
	},
	update(el, binding) {
		openLoading(getContainer(el, binding), binding)
	}
}

4.less 樣式代碼:

.jc-loading-mask {
	position: absolute;
	inset: 0;
	background-color: rgba(0, 0, 0, 0.7);
}
.jc-loading-spinner {
	position: absolute;
	left: calc(50% - 25px);
	top: calc(50% - 25px);
	width: 50px;
	height: 50px;
	animation: sp 4s linear infinite;
}
.jc-loading-spinner__circle {
	position: absolute;
	top: 0;
	left: calc(50% - 3px);
	width: 6px;
	height: 6px;
	transform: rotate(calc(var(--i) * (360deg / 12)));
	transform-origin: center 25px;
}
.jc-loading-spinner__circle::before {
	content: '';
	inset: 0;
	border-radius: 50%;
	position: absolute;
	background-color: #ff6348;
	animation: zoom 2.5s linear infinite;
	animation-delay: calc(var(--i) * 0.2s);
}
@keyframes sp {
	to {
		transform: rotate(360deg);
	}
}
@keyframes zoom {
	0% {
		transform: scale(1.2);
	}
	50% {
		transform: scale(0.5);
	}
	100% {
		transform: scale(1.2);
	}
}

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

相關文章

  • Vue屏幕自適應三種實現方法詳解

    Vue屏幕自適應三種實現方法詳解

    在實際業(yè)務中,我們常用圖表來做數據統(tǒng)計,數據展示,數據可視化等比較直觀的方式來達到一目了然的數據查看,但在大屏開發(fā)過程中,常會因為適配不同屏幕而感到困擾,下面我們來解決一下這個不算難題的難題
    2022-11-11
  • vue+elementUi中的table實現跨頁多選功能(示例詳解)

    vue+elementUi中的table實現跨頁多選功能(示例詳解)

    最近在開發(fā)工業(yè)品超市的后臺系統(tǒng),遇到一個需求,就是實現在一個table表格中多選數據,在網上查了好多,有些方法真的是無語,下面通過本文給大家分享vue+elementUi中的table實現跨頁多選功能,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • Vue中的驗證登錄狀態(tài)的實現方法

    Vue中的驗證登錄狀態(tài)的實現方法

    這篇文章主要介紹了Vue中的驗證登錄狀態(tài)的實現方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • vuex中的5個屬性使用方法舉例講解

    vuex中的5個屬性使用方法舉例講解

    vuex是專門為Vue.js應用程序開發(fā)的狀態(tài)管理模式,下面這篇文章主要給大家介紹了關于vuex中5個屬性使用方法的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-04-04
  • VUE axios發(fā)送跨域請求需要注意的問題

    VUE axios發(fā)送跨域請求需要注意的問題

    本篇文章主要介紹了VUE axios發(fā)送跨域請求需要注意的問題,在實際項目中前端使用到vue,后端使用php進行開發(fā)。前端使用axios請求請求遇到的問題,有興趣的可以了解一下
    2017-07-07
  • Vue實現數據導出導入實戰(zhàn)案例

    Vue實現數據導出導入實戰(zhàn)案例

    我們經常需要在Vue搭建的后臺管理系統(tǒng)里進行數據導入導出等操作,下面這篇文章主要給大家介紹了關于Vue實現數據導出導入實戰(zhàn)案例的相關資料,需要的朋友可以參考下
    2023-01-01
  • Vue?+?Element?自定義上傳封面組件功能

    Vue?+?Element?自定義上傳封面組件功能

    這篇文章主要介紹了Vue?+?Element?自定義上傳封面組件,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-01-01
  • Vue多選列表組件深入詳解

    Vue多選列表組件深入詳解

    這篇文章主要介紹了Vue多選列表組件深入詳解,這個是vue的基本組件,有需要的同學可以研究下
    2021-03-03
  • 使用vue完成微信公眾號網頁小記(推薦)

    使用vue完成微信公眾號網頁小記(推薦)

    公司最近有一個H5頁面的功能,比較簡單的一個調查表功能,嵌套在我們微信公眾號里面。這篇文章主要介紹了使用vue完成微信公眾號網頁小記,需要的朋友可以參考下
    2019-04-04
  • vue數據更新UI不刷新顯示的解決辦法

    vue數據更新UI不刷新顯示的解決辦法

    這篇文章主要介紹了vue數據更新UI不刷新顯示的解決辦法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08

最新評論