Loading
Loading (로딩 표시)
명령이 실행 중임을 알리고 기다림을 표시하는 컴포넌트예요.
출처: 문서
본문
언제 사용하나요
명령 실행이 오래 걸릴 때(수 초 이상) 실행 중이라는 상태를 사용자에게 보여줘요.
기본 사용법
테이블 데이터를 불러오는 상황을 예로 든 기본 사용법이에요. :::demo
<template>
<d-button @click="fetchTableData" style="margin-top: 8px">click me!</d-button>
<table
v-loading="loadingStatus"
:backdrop="true"
position-type="relative"
:view="{ top: '50%', left: '50%' }"
:z-index="100"
style="width: 100%; text-align: left;"
>
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>队伍</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(val, index) in datas" :key="index">
<td>{{ index }}</td>
<td>张家齐</td>
<td>跳水</td>
<td>跳水队</td>
</tr>
</tbody>
</table>
</template>
<script>
import { defineComponent, ref, reactive } from 'vue'
export default defineComponent({
setup() {
const loadingStatus = ref(false)
const datas = reactive([])
const fetchTableData = () => {
loadingStatus.value = true
setTimeout(() => {
datas.push(1, 2, 3)
loadingStatus.value = false
}, 2000)
}
return {
datas,
loadingStatus,
fetchTableData
}
}
})
</script>
:::
여러 promise
여러 개의 promise를 지원해요. :::demo
<template>
<d-button @click="fetchMutiplePromise" style="margin-top: 8px">click me!</d-button>
<div
v-loading="promises"
message="One moment please..."
style="margin-top: 20px; width: 100%; height: 80px; padding: 10px;"
>
loading will show here2
</div>
</template>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup() {
const promises = ref([])
const fetchMutiplePromise = () => {
let list = []
for (let i = 0; i < 3; i++) {
list.push(
new Promise((res, rej) => {
setTimeout(() => {
res(i)
}, (i + 1) * 1000)
}).then((res) => {
return res
})
)
}
promises.value = list
}
return {
promises,
fetchMutiplePromise
}
}
})
</script>
:::
커스텀 스타일
templateRef로 loading 스타일을 커스터마이즈할 수 있어요. :::demo
<template>
<d-button @click="showLoading1" style="margin-right: 8px; display: inline-block; width: 220px;">
Loading Style 1
</d-button>
<d-button
v-loading="isShowLoading2"
@click="showLoading2"
:loading-template-ref="temp2"
style="margin-right: 8px; display: inline-block; width: 220px;"
>
Loading Style 2
</d-button>
<d-button
v-loading="true"
variant="text"
:loading-template-ref="temp3"
style="margin-right: 8px; display: inline-block; width: 220px;"
>
Loading Style 3
</d-button>
<div
style="height: 80px; line-height: 80px"
v-loading="isShowLoading1"
:loading-template-ref="temp1"
>
loading will show here1
</div>
</template>
<script>
import { defineComponent, ref, h } from 'vue'
export default defineComponent({
setup() {
const temp1 = h(
'div',
{
className: 'devui-infinity-loading'
},
h('i', {
className: 'icon-refresh'
})
)
const temp2 = h(
'div',
{
className: 'devui-circle-loading-container-2'
},
h('i', {
className: 'icon-refresh'
})
)
const temp3 = h(
'div',
{
className: 'devui-circle-loading-container-3'
},
h('i', {
className: 'icon-refresh'
})
)
const isShowLoading1 = ref(false)
const showLoading1 = () => {
isShowLoading1.value = new Promise((res) => {
setTimeout(() => {
res(true)
}, 1000)
})
}
const isShowLoading2 = ref(false)
const showLoading2 = () => {
isShowLoading2.value = new Promise((res) => {
setTimeout(() => {
res(true)
}, 1000)
})
}
return {
temp1,
temp2,
temp3,
isShowLoading1,
isShowLoading2,
showLoading1,
showLoading2
}
}
})
</script>
<style>
.devui-infinity-loading {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.devui-circle-loading-container-2 {
position: absolute;
left: 5px;
top: 50%;
transform: translateY(-50%);
}
.devui-circle-loading-container-3 {
position: absolute;
right: -20px;
top: 50%;
transform: translateY(-50%);
}
</style>
:::
서비스 방식으로 호출하기
서비스 방식으로 화면 전체에 loading 컴포넌트를 띄우거나, 지정한 호스트 위에 loading 컴포넌트를 띄울 수 있어요. :::demo
<template>
<d-button class="mr-1" @click="serviceToBody">
click me show full screen loading!
</d-button>
<d-button v-if="isShow" @click="openTargetLoading">
click me show loading in target!
</d-button>
<d-button v-else @click="closeTargetLoading">
click me close loading in target!
</d-button>
<div id="me" class="mt-3" style="width: 100%; height: 60px; padding: 10px;">
loading will show here3
</div>
</template>
<script>
import { defineComponent, ref } from 'vue'
export default {
data() {
return {
isShow: true,
resultTarget: null
}
},
methods: {
serviceToBody() {
const results = this.$loadingService.open()
setTimeout(() => {
results.loadingInstance.close()
}, 2000)
},
openTargetLoading() {
this.resultTarget = this.$loadingService.open({
target: document.querySelector('#me'),
message: 'One moment please...',
positionType: 'relative',
zIndex: 1
})
this.isShow = false
},
closeTargetLoading() {
this.resultTarget.loadingInstance.close()
this.isShow = true
}
}
}
</script>
:::
Loading 파라미터
| 파라미터 | 타입 | 기본값 | 설명 | Demo 링크 |
|---|---|---|---|---|
| v-loading | Promise<any> | Array<Promise<any>> | Boolean | undefined |
-- | 선택, 디렉티브 방식. loading 상태 제어 | 기본 사용법 |
| target | element |
document.body | 선택, 서비스 방식. Loading이 덮을 DOM 노드 |
서비스 방식 호출 |
| message | string |
-- | 선택, loading 시 힌트 메시지 | 다중 promise |
| loading-template-ref | VNode |
-- | 선택, loading 템플릿 커스텀 | 커스텀 스타일 |
| backdrop | boolean |
true | 선택, loading 시 오버레이 표시 여부 | 기본 사용법 |
| position-type | string |
relative | 선택, loading 호스트 요소의 position 타입 지정. 값은 css position 속성과 동일 |
기본 사용법 |
| view | { top?: string, left?: string } |
{ top: '50%', left: '50%' } |
선택, loading 표시 위치 조정. 호스트 요소 기준 상단/왼쪽 거리 |
기본 사용법 |
| z-index | number |
-- | 선택, loading 힌트의 z-index 값 | 기본 사용법 |
더 알아보기 (Learn more)
v-loading 디렉티브 방식과 $loadingService 서비스 방식 두 가지를 상황에 맞게 골라 쓸 수 있어요.