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

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

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

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

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

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

具體實現(xiàn)

封裝準備

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

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

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

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.查看一下指令內(nèi)的輸出語句是否正常執(zhí)行,如圖:

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

實現(xiàn) loading 效果

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

// 導入模塊化的 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)建子元素進行旋轉(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.代碼還是非常簡單的,具體取決于你本身實現(xiàn)的 loading 效果,我這個是一個比較簡單的動效,上面這個地方如果有疑問那應該就是證據(jù)導入語句,在 vue 中,如果希望一個 less 文件作為一個模塊導入和使用,需要將文件命名改為 文件名.module.less 這種格式,即文件后綴為 .module.less,我們在 inserted 鉤子函數(shù)中打印一下這個導入的 styles,如下:

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

3.結(jié)果如圖:

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

loading 顯示與隱藏

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

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

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

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

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

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

5.而 update 函數(shù)中的代碼是不是也可以寫出來了,進行條件判斷來執(zhí)行邏輯,而且不難發(fā)現(xiàn)其實這個條件與 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.當然,還需要考慮當前顯示加載元素的 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.元素實際插入的位置,如圖:

完整代碼與結(jié)語

1.現(xiàn)在已經(jīng)具備了一個 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);
	}
}

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

相關文章

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

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

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

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

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

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

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

    VUE django 跨域、csrf令牌的問題

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

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

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

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

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

    報錯[vuex] unknown action type: userLogin問

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

    vue項目無法刪除的問題及解決

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

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

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

    Vue狀態(tài)模式實現(xiàn)窗口停靠功能(靈動、自由, 管理后臺Admin界面)

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

最新評論

凌云县| 泸溪县| 延吉市| 兰西县| 寿宁县| 灵宝市| 化德县| 清流县| 涞水县| 辽宁省| 五家渠市| 乐都县| 江北区| 务川| 马龙县| 凤凰县| 称多县| 兰西县| 从江县| 龙游县| 仁怀市| 阳江市| 陇川县| 桐庐县| 连平县| 龙陵县| 留坝县| 长汀县| 梧州市| 当阳市| 于田县| 舒兰市| 皮山县| 佛冈县| 永安市| 济阳县| 翁源县| 宜黄县| 古丈县| 南康市| 沁源县|