Compare commits
2 Commits
03cee79b53
...
22dc129d8f
| Author | SHA1 | Date |
|---|---|---|
|
|
22dc129d8f | |
|
|
64d9f26c62 |
|
|
@ -1,5 +1,5 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en" class="bg-[#FCEEF3]">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
|
|
||||||
|
|
@ -1,251 +0,0 @@
|
||||||
<template>
|
|
||||||
<Teleport to="body">
|
|
||||||
<Transition name="dialog">
|
|
||||||
<div v-if="visible" class="dialog-overlay" @click.self="handleOverlayClick">
|
|
||||||
<div class="dialog-container">
|
|
||||||
<!-- 对话框头部 -->
|
|
||||||
<div class="dialog-header" v-if="title || $slots.title">
|
|
||||||
<slot name="title">{{ title }}</slot>
|
|
||||||
<button v-if="closable" class="dialog-close" @click="handleClose">
|
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M12 4L4 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
||||||
<path d="M4 4L12 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 对话框内容 -->
|
|
||||||
<div class="dialog-body">
|
|
||||||
<slot>{{ message }}</slot>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 对话框底部按钮区域 -->
|
|
||||||
<div class="dialog-footer" v-if="showFooter">
|
|
||||||
<slot name="footer">
|
|
||||||
<button v-if="showCancelButton" class="dialog-button dialog-button-cancel" @click="handleCancel">
|
|
||||||
{{ cancelButtonText }}
|
|
||||||
</button>
|
|
||||||
<button class="dialog-button dialog-button-confirm" @click="handleConfirm">
|
|
||||||
{{ confirmButtonText }}
|
|
||||||
</button>
|
|
||||||
</slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</Teleport>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { defineProps, defineEmits } from 'vue'
|
|
||||||
|
|
||||||
// Props 定义
|
|
||||||
const props = defineProps({
|
|
||||||
// 是否显示对话框
|
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 对话框标题
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 对话框消息内容(简单文本内容)
|
|
||||||
message: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 是否显示关闭按钮
|
|
||||||
closable: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
// 是否显示底部按钮区域
|
|
||||||
showFooter: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
// 是否显示取消按钮
|
|
||||||
showCancelButton: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
// 确认按钮文本
|
|
||||||
confirmButtonText: {
|
|
||||||
type: String,
|
|
||||||
default: '确认'
|
|
||||||
},
|
|
||||||
// 取消按钮文本
|
|
||||||
cancelButtonText: {
|
|
||||||
type: String,
|
|
||||||
default: '取消'
|
|
||||||
},
|
|
||||||
// 点击遮罩层是否可以关闭对话框
|
|
||||||
closeOnClickOverlay: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Emits 定义
|
|
||||||
const emit = defineEmits<{
|
|
||||||
// 关闭事件
|
|
||||||
close: []
|
|
||||||
// 确认事件
|
|
||||||
confirm: []
|
|
||||||
// 取消事件
|
|
||||||
cancel: []
|
|
||||||
}>()
|
|
||||||
|
|
||||||
// 处理关闭操作
|
|
||||||
const handleClose = () => {
|
|
||||||
emit('close')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理确认操作
|
|
||||||
const handleConfirm = () => {
|
|
||||||
emit('confirm')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理取消操作
|
|
||||||
const handleCancel = () => {
|
|
||||||
emit('cancel')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理点击遮罩层
|
|
||||||
const handleOverlayClick = () => {
|
|
||||||
if (props.closeOnClickOverlay) {
|
|
||||||
emit('close')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
/* 遮罩层样式 */
|
|
||||||
.dialog-overlay {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 对话框容器样式 */
|
|
||||||
.dialog-container {
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
|
||||||
width: 90%;
|
|
||||||
max-width: 500px;
|
|
||||||
max-height: 80vh;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 对话框头部样式 */
|
|
||||||
.dialog-header {
|
|
||||||
padding: 16px 20px;
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 关闭按钮样式 */
|
|
||||||
.dialog-close {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
padding: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
color: #999;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-close:hover {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 对话框内容样式 */
|
|
||||||
.dialog-body {
|
|
||||||
padding: 20px;
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
color: #666;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 对话框底部样式 */
|
|
||||||
.dialog-footer {
|
|
||||||
padding: 16px 20px;
|
|
||||||
border-top: 1px solid #f0f0f0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 按钮样式 */
|
|
||||||
.dialog-button {
|
|
||||||
padding: 8px 16px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: none;
|
|
||||||
font-size: 14px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.2s;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-button-cancel {
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-button-cancel:hover {
|
|
||||||
background-color: #e8e8e8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-button-confirm {
|
|
||||||
background-color: #1890ff;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-button-confirm:hover {
|
|
||||||
background-color: #40a9ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 动画样式 */
|
|
||||||
.dialog-enter-active,
|
|
||||||
.dialog-leave-active {
|
|
||||||
transition: opacity 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-enter-from,
|
|
||||||
.dialog-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-enter-active .dialog-container,
|
|
||||||
.dialog-leave-active .dialog-container {
|
|
||||||
transition: transform 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-enter-from .dialog-container {
|
|
||||||
transform: scale(0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-leave-to .dialog-container {
|
|
||||||
transform: scale(0.9);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
||||||
import { createApp, h, nextTick } from 'vue'
|
|
||||||
import Dialog from './Dialog.vue'
|
|
||||||
|
|
||||||
// 对话框配置接口
|
|
||||||
export interface DialogOptions {
|
|
||||||
// 对话框标题
|
|
||||||
title?: string
|
|
||||||
// 对话框内容
|
|
||||||
message?: string
|
|
||||||
// 是否显示关闭按钮
|
|
||||||
closable?: boolean
|
|
||||||
// 是否显示底部按钮区域
|
|
||||||
showFooter?: boolean
|
|
||||||
// 是否显示取消按钮
|
|
||||||
showCancelButton?: boolean
|
|
||||||
// 确认按钮文本
|
|
||||||
confirmButtonText?: string
|
|
||||||
// 取消按钮文本
|
|
||||||
cancelButtonText?: string
|
|
||||||
// 点击遮罩层是否可以关闭对话框
|
|
||||||
closeOnClickOverlay?: boolean
|
|
||||||
// 确认回调函数
|
|
||||||
onConfirm?: () => void
|
|
||||||
// 取消回调函数
|
|
||||||
onCancel?: () => void
|
|
||||||
// 关闭回调函数
|
|
||||||
onClose?: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dialog 实例接口
|
|
||||||
interface DialogInstance {
|
|
||||||
show: () => void
|
|
||||||
hide: () => void
|
|
||||||
close: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并显示一个对话框
|
|
||||||
* @param options 对话框配置选项
|
|
||||||
* @returns 对话框实例,可用于手动控制显示和隐藏
|
|
||||||
*/
|
|
||||||
export function showDialog(options: DialogOptions): DialogInstance {
|
|
||||||
// 默认配置
|
|
||||||
const defaultOptions: DialogOptions = {
|
|
||||||
title: '',
|
|
||||||
message: '',
|
|
||||||
closable: true,
|
|
||||||
showFooter: true,
|
|
||||||
showCancelButton: true,
|
|
||||||
confirmButtonText: '确认',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
closeOnClickOverlay: true,
|
|
||||||
onConfirm: () => {},
|
|
||||||
onCancel: () => {},
|
|
||||||
onClose: () => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并配置
|
|
||||||
const mergedOptions = { ...defaultOptions, ...options }
|
|
||||||
|
|
||||||
// 创建一个容器元素
|
|
||||||
const container = document.createElement('div')
|
|
||||||
|
|
||||||
// 对话框状态
|
|
||||||
let visible = true
|
|
||||||
|
|
||||||
// 创建应用实例
|
|
||||||
const app = createApp({
|
|
||||||
render() {
|
|
||||||
return h(Dialog, {
|
|
||||||
visible,
|
|
||||||
title: mergedOptions.title,
|
|
||||||
message: mergedOptions.message,
|
|
||||||
closable: mergedOptions.closable,
|
|
||||||
showFooter: mergedOptions.showFooter,
|
|
||||||
showCancelButton: mergedOptions.showCancelButton,
|
|
||||||
confirmButtonText: mergedOptions.confirmButtonText,
|
|
||||||
cancelButtonText: mergedOptions.cancelButtonText,
|
|
||||||
closeOnClickOverlay: mergedOptions.closeOnClickOverlay,
|
|
||||||
onConfirm: () => {
|
|
||||||
mergedOptions.onConfirm?.()
|
|
||||||
hideDialog()
|
|
||||||
},
|
|
||||||
onCancel: () => {
|
|
||||||
mergedOptions.onCancel?.()
|
|
||||||
hideDialog()
|
|
||||||
},
|
|
||||||
onClose: () => {
|
|
||||||
mergedOptions.onClose?.()
|
|
||||||
hideDialog()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 隐藏对话框
|
|
||||||
function hideDialog() {
|
|
||||||
visible = false
|
|
||||||
// 等待动画完成后卸载组件
|
|
||||||
nextTick(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
app.unmount()
|
|
||||||
if (container.parentNode) {
|
|
||||||
container.parentNode.removeChild(container)
|
|
||||||
}
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示对话框(默认为显示状态)
|
|
||||||
function showDialog() {
|
|
||||||
visible = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 挂载组件
|
|
||||||
app.mount(container)
|
|
||||||
document.body.appendChild(container)
|
|
||||||
|
|
||||||
// 返回控制方法
|
|
||||||
return {
|
|
||||||
show: showDialog,
|
|
||||||
hide: hideDialog,
|
|
||||||
close: hideDialog
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示一个确认对话框
|
|
||||||
* @param message 确认消息
|
|
||||||
* @param title 对话框标题
|
|
||||||
* @param onConfirm 确认回调
|
|
||||||
* @returns 对话框实例
|
|
||||||
*/
|
|
||||||
export function showConfirmDialog(message: string, title: string = '确认', onConfirm?: () => void): DialogInstance {
|
|
||||||
return showDialog({
|
|
||||||
title,
|
|
||||||
message,
|
|
||||||
showCancelButton: true,
|
|
||||||
onConfirm
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示一个提示对话框
|
|
||||||
* @param message 提示消息
|
|
||||||
* @param title 对话框标题
|
|
||||||
* @returns 对话框实例
|
|
||||||
*/
|
|
||||||
export function showAlertDialog(message: string, title: string = '提示'): DialogInstance {
|
|
||||||
return showDialog({
|
|
||||||
title,
|
|
||||||
message,
|
|
||||||
showCancelButton: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 默认导出
|
|
||||||
export default {
|
|
||||||
show: showDialog,
|
|
||||||
confirm: showConfirmDialog,
|
|
||||||
alert: showAlertDialog
|
|
||||||
}
|
|
||||||
|
|
@ -1,304 +0,0 @@
|
||||||
# Loading 组件使用文档
|
|
||||||
|
|
||||||
## 组件介绍
|
|
||||||
|
|
||||||
Loading 组件是一个灵活的加载动画组件,支持多种动画类型、自定义大小、颜色等配置,可用于页面加载、数据请求等场景。
|
|
||||||
|
|
||||||
## 组件类型
|
|
||||||
|
|
||||||
- `spinner`:旋转圆环(默认)
|
|
||||||
- `dots`:点状加载动画
|
|
||||||
- `pulse`:脉冲加载动画
|
|
||||||
- `ring`:环形旋转动画
|
|
||||||
|
|
||||||
## 使用方式
|
|
||||||
|
|
||||||
### 方式一:组件方式使用
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<!-- 基本使用 -->
|
|
||||||
<Loading :visible="loadingVisible" />
|
|
||||||
|
|
||||||
<!-- 自定义配置 -->
|
|
||||||
<Loading
|
|
||||||
:visible="loadingVisible"
|
|
||||||
type="dots"
|
|
||||||
size="60"
|
|
||||||
color="#1890ff"
|
|
||||||
text="加载中..."
|
|
||||||
:fullscreen="true"
|
|
||||||
background="rgba(0, 0, 0, 0.7)"
|
|
||||||
:opacity="0.8"
|
|
||||||
:strokeWidth="4"
|
|
||||||
strokeLinecap="round"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<button @click="showLoading">显示加载</button>
|
|
||||||
<button @click="hideLoading">隐藏加载</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import Loading from './Loading.vue'
|
|
||||||
|
|
||||||
const loadingVisible = ref(false)
|
|
||||||
|
|
||||||
function showLoading() {
|
|
||||||
loadingVisible.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideLoading() {
|
|
||||||
loadingVisible.value = false
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方式二:编程方式使用
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<button @click="showFullscreenLoading">显示全屏加载</button>
|
|
||||||
<button @click="showLoadingWithText">显示带文本的加载</button>
|
|
||||||
<button @click="showInlineLoading">显示内联加载</button>
|
|
||||||
<button @click="hideAllLoading">隐藏所有加载</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { showLoading, hideLoading, showLoadingWithText, showInlineLoading } from './loading'
|
|
||||||
import type { LoadingInstance } from './loading'
|
|
||||||
|
|
||||||
// 保存加载实例
|
|
||||||
let loadingInstance: LoadingInstance | null = null
|
|
||||||
|
|
||||||
// 显示全屏加载
|
|
||||||
function showFullscreenLoading() {
|
|
||||||
loadingInstance = showLoading({
|
|
||||||
type: 'spinner',
|
|
||||||
size: 50,
|
|
||||||
color: '#1890ff',
|
|
||||||
fullscreen: true,
|
|
||||||
background: 'rgba(255, 255, 255, 0.9)'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示带文本的加载
|
|
||||||
function showLoadingWithText() {
|
|
||||||
loadingInstance = showLoadingWithText('数据加载中,请稍候...', '#52c41a')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示内联加载
|
|
||||||
function showInlineLoading() {
|
|
||||||
loadingInstance = showInlineLoading(32, '#fa8c16', 'dots')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 隐藏所有加载
|
|
||||||
function hideAllLoading() {
|
|
||||||
// 方式1:隐藏特定实例
|
|
||||||
if (loadingInstance) {
|
|
||||||
loadingInstance.hide()
|
|
||||||
loadingInstance = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// 方式2:隐藏当前活动的全屏加载(如果有的话)
|
|
||||||
hideLoading()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 模拟异步请求
|
|
||||||
function mockAsyncRequest() {
|
|
||||||
const loading = showLoadingWithText('处理中...')
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
// 请求完成后隐藏加载
|
|
||||||
loading.hide()
|
|
||||||
console.log('请求完成')
|
|
||||||
}, 3000)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
## API 文档
|
|
||||||
|
|
||||||
### Loading 组件 Props
|
|
||||||
|
|
||||||
| 属性名 | 类型 | 默认值 | 说明 |
|
|
||||||
|-------|------|-------|------|
|
|
||||||
| visible | boolean | false | 是否显示加载组件 |
|
|
||||||
| type | 'spinner' \| 'dots' \| 'pulse' \| 'ring' | 'spinner' | 加载动画类型 |
|
|
||||||
| size | number \| string | 40 | 加载动画大小 |
|
|
||||||
| color | string | '#1890ff' | 加载动画颜色 |
|
|
||||||
| fullscreen | boolean | true | 是否全屏显示 |
|
|
||||||
| text | string | '' | 加载文本 |
|
|
||||||
| background | string | 'rgba(255, 255, 255, 0.9)' | 遮罩层背景色(全屏模式下) |
|
|
||||||
| opacity | number | 1 | 遮罩层透明度(全屏模式下) |
|
|
||||||
| strokeWidth | number | 3 | 线条宽度(仅适用于spinner和ring类型) |
|
|
||||||
| strokeLinecap | 'round' \| 'butt' \| 'square' | 'round' | 线条末端样式(仅适用于spinner类型) |
|
|
||||||
|
|
||||||
### loading.ts 函数API
|
|
||||||
|
|
||||||
#### showLoading(options?: LoadingOptions): LoadingInstance
|
|
||||||
|
|
||||||
创建并显示一个加载组件。
|
|
||||||
|
|
||||||
**参数**:
|
|
||||||
- options: LoadingOptions - 加载组件配置选项(与组件Props相同)
|
|
||||||
|
|
||||||
**返回值**:
|
|
||||||
- LoadingInstance - 加载组件实例,包含 show()、hide()、close() 方法
|
|
||||||
|
|
||||||
#### hideLoading(): void
|
|
||||||
|
|
||||||
隐藏当前活动的全屏加载组件。
|
|
||||||
|
|
||||||
#### showLoadingWithText(text: string, color?: string): LoadingInstance
|
|
||||||
|
|
||||||
显示一个带有文本的全屏加载组件。
|
|
||||||
|
|
||||||
**参数**:
|
|
||||||
- text: string - 加载文本
|
|
||||||
- color: string - 加载动画颜色,默认为 '#1890ff'
|
|
||||||
|
|
||||||
**返回值**:
|
|
||||||
- LoadingInstance - 加载组件实例
|
|
||||||
|
|
||||||
#### showInlineLoading(size?: number, color?: string, type?: LoadingType): LoadingInstance
|
|
||||||
|
|
||||||
显示一个小型内联加载组件。
|
|
||||||
|
|
||||||
**参数**:
|
|
||||||
- size: number - 加载组件大小,默认为 24
|
|
||||||
- color: string - 加载动画颜色,默认为 '#1890ff'
|
|
||||||
- type: LoadingType - 加载动画类型,默认为 'spinner'
|
|
||||||
|
|
||||||
**返回值**:
|
|
||||||
- LoadingInstance - 加载组件实例
|
|
||||||
|
|
||||||
### LoadingInstance 接口
|
|
||||||
|
|
||||||
| 方法名 | 说明 |
|
|
||||||
|-------|------|
|
|
||||||
| show() | 显示加载组件 |
|
|
||||||
| hide() | 隐藏加载组件并卸载 |
|
|
||||||
| close() | 同 hide(),隐藏加载组件并卸载 |
|
|
||||||
|
|
||||||
## 示例代码
|
|
||||||
|
|
||||||
### 场景1:页面加载
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<template>
|
|
||||||
<div v-if="!loading">
|
|
||||||
<!-- 页面内容 -->
|
|
||||||
</div>
|
|
||||||
<Loading v-else :visible="loading" text="页面加载中..." />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, onMounted } from 'vue'
|
|
||||||
import Loading from './components/Loading.vue'
|
|
||||||
|
|
||||||
const loading = ref(true)
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 模拟页面数据加载
|
|
||||||
setTimeout(() => {
|
|
||||||
loading.value = false
|
|
||||||
}, 2000)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 场景2:API请求加载
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<button @click="fetchData" :disabled="loading">获取数据</button>
|
|
||||||
<div v-if="data">
|
|
||||||
<!-- 数据展示 -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { showLoading, hideLoading } from './components/loading'
|
|
||||||
|
|
||||||
const loading = ref(false)
|
|
||||||
const data = ref(null)
|
|
||||||
|
|
||||||
async function fetchData() {
|
|
||||||
loading.value = true
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 显示加载
|
|
||||||
const loadingInstance = showLoadingWithText('数据请求中...')
|
|
||||||
|
|
||||||
// 模拟API请求
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 2000))
|
|
||||||
|
|
||||||
// 获取数据
|
|
||||||
data.value = { /* 数据内容 */ }
|
|
||||||
} catch (error) {
|
|
||||||
console.error('请求失败:', error)
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
// 隐藏加载
|
|
||||||
hideLoading()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 场景3:提交表单时的加载
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<template>
|
|
||||||
<form @submit.prevent="submitForm">
|
|
||||||
<!-- 表单内容 -->
|
|
||||||
<button type="submit" :disabled="submitting">
|
|
||||||
{{ submitting ? '提交中...' : '提交' }}
|
|
||||||
<Loading
|
|
||||||
v-if="submitting"
|
|
||||||
:visible="true"
|
|
||||||
:fullscreen="false"
|
|
||||||
type="spinner"
|
|
||||||
:size="16"
|
|
||||||
style="display: inline-block; margin-left: 8px;"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import Loading from './components/Loading.vue'
|
|
||||||
|
|
||||||
const submitting = ref(false)
|
|
||||||
|
|
||||||
async function submitForm() {
|
|
||||||
submitting.value = true
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 模拟表单提交
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 1500))
|
|
||||||
console.log('表单提交成功')
|
|
||||||
} catch (error) {
|
|
||||||
console.error('表单提交失败:', error)
|
|
||||||
} finally {
|
|
||||||
submitting.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. 当使用编程方式创建多个全屏加载组件时,最新创建的会替换之前的。
|
|
||||||
2. 请确保在不需要加载动画时调用 hide() 方法来卸载组件,避免内存泄漏。
|
|
||||||
3. 对于长时间运行的操作,建议添加加载文本以提高用户体验。
|
|
||||||
4. 内联加载组件不会自动居中,需要根据具体场景调整其位置。
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="min-h-screen bg-[#FCEEF3] overflow-hidden">
|
<div class="h-full bg-[#FCEEF3] overflow-hidden">
|
||||||
<!-- 顶部头图 -->
|
<!-- 顶部头图 -->
|
||||||
<div class="w-full overflow-hidden relative">
|
<div class="w-full overflow-hidden relative">
|
||||||
<img src="/头图.png" alt="活动宣传" class="w-full h-auto" />
|
<img src="/头图.png" alt="活动宣传" class="w-full h-auto" />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue