Loading 로딩
로딩 중 피드백. 세 가지 형태: 서비스 방식 오버레이(LhLoading.show(...), 전체 화면 또는 지정 컨테이너), v-loading 디렉티브, 기본 회전 그래픽 LhSpinner.
서비스 방식 전체 화면 오버레이
<script setup lang="ts">
import { LhLoading } from '@lh-ui/vue3'
const showFullscreen = () => {
const handle = LhLoading.show({ fullscreen: true, lock: true })
setTimeout(() => handle.close(), 2000)
}
</script>
<template>
<LhButton @click="showFullscreen">전체 화면 로딩 2초</LhButton>
</template><script>
import { LhLoading } from '@lh-ui/vue3'
export default {
methods: {
showFullscreen() {
const handle = LhLoading.show({ fullscreen: true, lock: true })
setTimeout(() => handle.close(), 2000)
},
},
}
</script>
<template>
<LhButton @click="showFullscreen">전체 화면 로딩 2초</LhButton>
</template>지정 컨테이너 오버레이
target을 넘기지 않으면 전체 화면이 됩니다; 선택자나 요소를 넘기면 컨테이너 안에 펼쳐집니다(absolute로 가장 가까운 위치 지정 조상을 채우고, static 컨테이너는 자동으로 relative를 보충하며 닫을 때 원복합니다).
<script setup lang="ts">
import { ref } from 'vue'
import { LhLoading } from '@lh-ui/vue3'
const boxRef = ref<HTMLElement>()
const showBox = () => {
const handle = LhLoading.show({ target: boxRef.value, text: '로딩 중', lock: true })
setTimeout(() => handle.close(), 2000)
}
</script>
<template>
<div
ref="boxRef"
class="demo-loading-box"
>
<LhButton @click="showBox">컨테이너 내 로딩</LhButton>
</div>
</template><script>
import { LhLoading } from '@lh-ui/vue3'
export default {
methods: {
showBox() {
const handle = LhLoading.show({ target: this.$refs.boxRef, text: '로딩 중', lock: true })
setTimeout(() => handle.close(), 2000)
},
},
}
</script>
<template>
<div
ref="boxRef"
class="demo-loading-box"
>
<LhButton @click="showBox">컨테이너 내 로딩</LhButton>
</div>
</template>v-loading 디렉티브
app.use(LhLoading)(또는 전체 임포트)로 v-loading 디렉티브를 등록하고, 불리언 값으로 표시/숨김을 제어합니다.
<template>
<div v-loading="busy" class="table-zone">…</div>
<div v-loading:text="'커스텀 문구'" :style="busy2 ? 'height:200px' : ''">…</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const busy = ref(false)
const busy2 = ref(false)
</script><template>
<div v-loading="busy" class="table-zone">…</div>
<div v-loading:text="'커스텀 문구'" :style="busy2 ? 'height:200px' : ''">…</div>
</template>
<script>
export default {
data() {
return { busy: false, busy2: false }
},
}
</script>LhSpinner 회전 그래픽
기본 회전 그래픽으로 단독으로 사용할 수 있습니다(loading 시맨틱 오버레이 내부에도 동일하게 렌더링됩니다).
<script setup lang="ts">
</script>
<template>
<div class="demo-loading-row">
<LhSpinner size="small" />
<LhSpinner size="medium" />
<LhSpinner size="large" color="#8f9779" />
</div>
</template><script>
export default {}
</script>
<template>
<div class="demo-loading-row">
<LhSpinner size="small" />
<LhSpinner size="medium" />
<LhSpinner size="large" color="#8f9779" />
</div>
</template>커스텀 외관
text로 안내 문구를, background로 오버레이 배경을, z-index로 쌓임 순서를, spinner로 회전 그래픽을 끕니다.
<script setup lang="ts">
import { LhLoading } from '@lh-ui/vue3'
const showStyled = () => {
const handle = LhLoading.show({
text: '데이터 동기화 중…',
background: 'rgba(42, 37, 32, 0.6)',
zIndex: 4000,
spinner: false,
})
setTimeout(() => handle.close(), 2000)
}
</script>
<template>
<LhButton @click="showStyled">커스텀 외관 로딩 2초</LhButton>
</template><script>
import { LhLoading } from '@lh-ui/vue3'
export default {
methods: {
showStyled() {
const handle = LhLoading.show({
text: '데이터 동기화 중…',
background: 'rgba(42, 37, 32, 0.6)',
zIndex: 4000,
spinner: false,
})
setTimeout(() => handle.close(), 2000)
},
},
}
</script>
<template>
<LhButton @click="showStyled">커스텀 외관 로딩 2초</LhButton>
</template>API
LhLoadingMask Props
| 프로퍼티 | 설명 | 타입 | 기본값 |
|---|---|---|---|
| fullscreen | 전체 화면 여부(대상이 body일 때 true) | boolean | — |
| text | 로딩 안내 문구(넘기지 않으면 언어 팩 loading.text 사용) | string | — |
| background | 오버레이 배경색(CSS background 값) | string | — |
| zIndex | 쌓임 순서 | number | — |
| spinner | 회전 그래픽 표시 여부 | boolean | true |
| sx | sx 빠른 레이아웃 속성 | LhSxProps | — |
서비스: LhLoading.show({ target?, text?, background?, lock?, spinner?, sx? })가 { close }를 반환합니다; app.use(LhLoading)로 v-loading 디렉티브를 등록합니다.
접근성
- 오버레이는
role="status"+aria-busy="true"이며, 안내 문구가aria-label로 읽힙니다 - 컨테이너를 지정한 경우
inert를 사용할 수 있으면(점진적 향상) 컨테이너가 키보드와 보조 기술에 닿지 않게 되어 하위 데이터 조작을 방지합니다 lock은 스크롤을 잠그고 닫을 때 원복합니다; 오버레이가 닫힐 때 컨테이너의 원래 위치와 스크롤 상태를 복원합니다- 회전 애니메이션은
prefers-reduced-motion을 존중합니다
타입 정의
이 컴포넌트가 외부로 노출하는 TypeScript 타입 구조는 다음과 같습니다(packages/components/loading/src/types.ts와 @lh-ui/share/core/* 소스에서 자동 추출, 각 항목을 클릭하여 전체 정의를 펼쳐 볼 수 있습니다; 프로퍼티 설명은 위쪽 Props 표를 참고하세요):
LhLoadingMaskProps
/** 오버레이 컴포넌트 props(서비스/디렉티브 내부 렌더링) */
export interface LhLoadingMaskProps {
/** 전체 화면 여부(대상이 body일 때 true) */
fullscreen?: boolean
/** 로딩 안내 문구(넘기지 않으면 언어 팩 loading.text 사용) */
text?: string
/** 오버레이 배경색(CSS background 값) */
background?: string
/** 쌓임 순서 */
zIndex?: number
/** 회전 그래픽 표시 여부(기본값 true) */
spinner?: boolean
sx?: LhSxProps
}LhLoadingOptions (출처: @lh-ui/share/core/loading)
/** 로딩 오버레이 옵션(서비스와 디렉티브 공통) */
export interface LhLoadingOptions {
/** 마운트 대상: 선택자 문자열 / 요소; 넘기지 않으면 전체 화면 */
target?: string | HTMLElement
/** 로딩 안내 문구(넘기지 않으면 언어 팩 loading.text 사용) */
text?: string
/** 오버레이 배경색(CSS background 값) */
background?: string
/** 스크롤 잠금 여부(전체 화면 오버레이는 body를 잠그고, 대상 지정 시 대상 자체의 스크롤을 잠금) */
lock?: boolean
/** 회전 그래픽 표시 여부 */
spinner?: boolean
sx?: LhSxProps
}LhLoadingHandle (출처: @lh-ui/share/core/loading)
/** 서비스 핸들 */
export interface LhLoadingHandle {
close: () => void
}