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

如何實(shí)現(xiàn)vue加載指令 v-loading

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

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

為什么使用指令實(shí)現(xiàn)

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

具體實(shí)現(xiàn)

封裝準(zhǔn)備

1.首先需要一個 js 文件,因?yàn)橹噶顚?shí)際上就是一個對象,通過在不同的鉤子函數(shù)中執(zhí)行對應(yīng)的邏輯,在本文中,需要使用的鉤子函數(shù)是 inserted 和 update,因此可以寫一個基礎(chǔ)的結(jié)構(gòu),如下:

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

2.然后將這個指令在入口文件 main.js 內(nèi)進(jìn)行全局注冊,如下:

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

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

<template>
	<div class="container">
		<button
			style="margin-bottom: 20px"
			@click="handleClick">
			開關(guān)
		</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.查看一下指令內(nèi)的輸出語句是否正常執(zhí)行,如圖:

5.正常進(jìn)行了打印,現(xiàn)在我們進(jìn)行正式的編寫

實(shí)現(xiàn) loading 效果

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

// 導(dǎo)入模塊化的 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 旋轉(zhuǎn)容器元素
	const loadingSpinner = document.createElement('div')
	loadingSpinner.classList.add(styles['jc-loading-spinner'])
	loadingMask.appendChild(loadingSpinner)
	// 創(chuàng)建文本片段
	const fragment = document.createDocumentFragment()
	// 創(chuàng)建子元素進(jìn)行旋轉(zhuǎn)縮放
	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.代碼還是非常簡單的,具體取決于你本身實(shí)現(xiàn)的 loading 效果,我這個是一個比較簡單的動效,上面這個地方如果有疑問那應(yīng)該就是證據(jù)導(dǎo)入語句,在 vue 中,如果希望一個 less 文件作為一個模塊導(dǎo)入和使用,需要將文件命名改為 文件名.module.less 這種格式,即文件后綴為 .module.less,我們在 inserted 鉤子函數(shù)中打印一下這個導(dǎo)入的 styles,如下:

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

3.結(jié)果如圖:

4.k 為 less 文件中開發(fā)時書寫的類名,而后面的 v 表示實(shí)際的類名,本案例中 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 樣式我就不再贅述了,先不進(jìn)行其他邏輯判斷,只展示到頁面上,看看效果,代碼如下:

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

6.效果如圖:

7.其實(shí)也不難對吧,這個效果你可以根據(jù)自己的需求來進(jìn)行更換,但是實(shí)現(xiàn)方法都是可以套用的

loading 顯示與隱藏

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

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

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

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

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

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

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

// 開啟加載效果
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.當(dāng)然,還需要考慮當(dāng)前顯示加載元素的 dom 是不是存在相對定位,如果不存在則改為相對定位,最后指令對象的實(shí)際代碼如下:

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.我們看一下實(shí)際的效果,如圖:

使用修飾符擴(kuò)展

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

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.元素實(shí)際插入的位置,如圖:

完整代碼與結(jié)語

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

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

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

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);
	}
}

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

相關(guān)文章

  • 詳解從vue的組件傳值著手觀察者模式

    詳解從vue的組件傳值著手觀察者模式

    本文詳細(xì)介紹了從vue的組件傳值著手觀察者模式,感興趣的同學(xué),可以參考下,理解其原理。
    2021-06-06
  • 5種vue模糊查詢的方法總結(jié)

    5種vue模糊查詢的方法總結(jié)

    在Vue中,有多種方式可以實(shí)現(xiàn)模糊查詢,這篇文章主要介紹了5種vue中的常用方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-08-08
  • 簡單說說如何使用vue-router插件的方法

    簡單說說如何使用vue-router插件的方法

    這篇文章主要介紹了如何使用vue-router插件的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • VUE django 跨域、csrf令牌的問題

    VUE django 跨域、csrf令牌的問題

    在Vue和Django進(jìn)行前后分離開發(fā)時,經(jīng)常會遇到跨域和CSRF令牌驗(yàn)證問題,本文詳細(xì)介紹了如何在Django后端設(shè)置視圖獲取CSRF令牌,并在Vue前端進(jìn)行配置以確保安全的數(shù)據(jù)交互,文章提供了后端視圖創(chuàng)建、settings配置以及前端axios請求封裝的具體方法
    2024-09-09
  • vue3前端實(shí)現(xiàn)全屏顯示及元素垂直填滿頁面效果

    vue3前端實(shí)現(xiàn)全屏顯示及元素垂直填滿頁面效果

    這篇文章主要給大家介紹了關(guān)于vue3前端實(shí)現(xiàn)全屏顯示及元素垂直填滿頁面效果的相關(guān)資料,文中還給大家介紹了vue3實(shí)現(xiàn)某一個元素全屏之后就黑屏了的解決辦法,需要的朋友可以參考下
    2024-02-02
  • Vue3?setup中使用$refs的方法詳解

    Vue3?setup中使用$refs的方法詳解

    在?Vue?3?中的?Composition?API?中,$refs?并不直接可用于?setup?函數(shù),但是實(shí)際工作中確實(shí)有需求,那么該如何解決呢,本文為大家整理了兩個方案,希望對大家有所幫助
    2023-08-08
  • 報錯[vuex] unknown action type: userLogin問題及解決

    報錯[vuex] unknown action type: userLogin問

    這篇文章主要介紹了報錯[vuex] unknown action type: userLogin問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue項(xiàng)目無法刪除的問題及解決

    vue項(xiàng)目無法刪除的問題及解決

    這篇文章主要介紹了vue項(xiàng)目無法刪除的問題及解決方案,具有很好的參考價值,希望對的大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue實(shí)現(xiàn)多窗口數(shù)據(jù)實(shí)時同步的三種常規(guī)方案詳解

    Vue實(shí)現(xiàn)多窗口數(shù)據(jù)實(shí)時同步的三種常規(guī)方案詳解

    要實(shí)現(xiàn)多窗口(或多標(biāo)簽頁)數(shù)據(jù)實(shí)時同步(無需刷新),核心是利用?瀏覽器跨窗口通信能力?結(jié)合?狀態(tài)管理,本文將介紹三種常規(guī)方案,希望對大家有所幫助
    2025-11-11
  • Vue狀態(tài)模式實(shí)現(xiàn)窗口停靠功能(靈動、自由, 管理后臺Admin界面)

    Vue狀態(tài)模式實(shí)現(xiàn)窗口??抗δ?靈動、自由, 管理后臺Admin界面)

    這篇文章主要介紹了Vue狀態(tài)模式實(shí)現(xiàn)窗口停靠功能(靈動、自由, 管理后臺Admin界面),本文通過實(shí)例代碼文字說明給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03

最新評論

新民市| 谢通门县| 枣阳市| 胶州市| 鄯善县| 闻喜县| 扎囊县| 黄陵县| 区。| 中阳县| 定陶县| 乐陵市| 连城县| 上栗县| 襄汾县| 光山县| 安图县| 东乡县| 乡宁县| 石泉县| 敦煌市| 嘉峪关市| 英吉沙县| 桐乡市| 蒲城县| 泰顺县| 防城港市| 曲阜市| 二连浩特市| 绥芬河市| 钟山县| 冀州市| 惠州市| 榆林市| 许昌市| 兴海县| 健康| 海南省| 湾仔区| 蛟河市| 商城县|