亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

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

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

封裝準(zhǔn)備

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

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

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

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

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

<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í)也非常的簡(jiǎn)單,找一個(gè)你覺得好看或者合適的加載效果,按照正常的 html+css+js 進(jìn)行實(shí)現(xiàn)就好,當(dāng)你實(shí)現(xiàn)好之后,需要做的就是使用 js 進(jìn)行動(dòng)態(tài)的創(chuàng)建這些元素,所以我們需要有一個(gè)函數(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.代碼還是非常簡(jiǎn)單的,具體取決于你本身實(shí)現(xiàn)的 loading 效果,我這個(gè)是一個(gè)比較簡(jiǎn)單的動(dòng)效,上面這個(gè)地方如果有疑問那應(yīng)該就是證據(jù)導(dǎo)入語句,在 vue 中,如果希望一個(gè) less 文件作為一個(gè)模塊導(dǎo)入和使用,需要將文件命名改為 文件名.module.less 這種格式,即文件后綴為 .module.less,我們?cè)?inserted 鉤子函數(shù)中打印一下這個(gè)導(dǎo)入的 styles,如下:

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

3.結(jié)果如圖:

4.k 為 less 文件中開發(fā)時(shí)書寫的類名,而后面的 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í)也不難對(duì)吧,這個(gè)效果你可以根據(jù)自己的需求來進(jìn)行更換,但是實(shí)現(xiàn)方法都是可以套用的

loading 顯示與隱藏

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

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

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

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

4.所以我們?cè)?inserted 鉤子函數(shù)中,應(yīng)該進(jìn)行判斷,當(dāng)指令的值為 true 且元素不存在時(shí),就創(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í)這個(gè)條件與 inserted 中的條件是重合的,所以我們可以封裝為一個(gè)函數(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 是不是存在相對(duì)定位,如果不存在則改為相對(duì)定位,最后指令對(duì)象的實(shí)際代碼如下:

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

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

使用修飾符擴(kuò)展

1.通過 modifiers(修飾符) 進(jìn)行一個(gè)擴(kuò)展,當(dāng)指令了添加了修飾符 body 的時(shí)候,loading 就會(huì)插入到 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.此時(shí)在組件中使用添加修飾符 body 即可,如下:

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

3.查看效果,如圖:

4.元素實(shí)際插入的位置,如圖:

完整代碼與結(jié)語

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

{ 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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue屏幕自適應(yīng)三種實(shí)現(xiàn)方法詳解

    Vue屏幕自適應(yīng)三種實(shí)現(xiàn)方法詳解

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

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

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

    Vue中的驗(yàn)證登錄狀態(tài)的實(shí)現(xiàn)方法

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

    vuex中的5個(gè)屬性使用方法舉例講解

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

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

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

    Vue實(shí)現(xiàn)數(shù)據(jù)導(dǎo)出導(dǎo)入實(shí)戰(zhàn)案例

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

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

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

    Vue多選列表組件深入詳解

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

    使用vue完成微信公眾號(hào)網(wǎng)頁小記(推薦)

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

    vue數(shù)據(jù)更新UI不刷新顯示的解決辦法

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

最新評(píng)論