Files
WAI_Project_UNIX/uni_modules/cool-ui/components/cl-confirm/cl-confirm.uvue
2025-07-23 18:30:43 +08:00

195 lines
4.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<cl-popup
v-model="visible"
:pt="{
className: '!rounded-[60rpx]'
}"
size="70%"
:show-close="false"
:show-header="false"
:mask-closable="false"
direction="center"
@mask-close="onAction('close')"
@closed="onClosed"
>
<view class="cl-confirm">
<cl-text
:pt="{
className: parseClass(['cl-confirm__title text-lg text-center font-bold mb-2'])
}"
>{{ config.title }}</cl-text
>
<cl-text
:pt="{
className: parseClass(['cl-confirm__message text-md text-center mb-8'])
}"
>{{ config.message }}</cl-text
>
<view class="cl-confirm__actions">
<cl-button
v-if="config.showCancel"
size="large"
text
rounded
border
type="info"
:pt="{
className: 'flex-1 h-[80rpx]'
}"
@tap="onAction('cancel')"
>{{ config.cancelText }}</cl-button
>
<cl-button
v-if="config.showConfirm"
size="large"
rounded
:loading="loading"
:pt="{
className: 'flex-1 h-[80rpx]'
}"
@tap="onAction('confirm')"
>{{ config.confirmText }}</cl-button
>
</view>
</view>
</cl-popup>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue";
import type { ClConfirmAction, ClConfirmOptions } from "../../types";
import { t } from "@/locale";
import { parseClass } from "@/cool";
// 控制弹窗显示/隐藏
const visible = ref(false);
// 控制弹窗是否关闭
const closed = ref(true);
// 确认弹窗配置项,包含标题、内容、按钮文本等
const config = reactive<ClConfirmOptions>({
title: "",
message: ""
});
// 控制确认按钮loading状态
const loading = ref(false);
// 显示loading
function showLoading() {
loading.value = true;
}
// 隐藏loading
function hideLoading() {
loading.value = false;
}
// 关闭弹窗
function close() {
visible.value = false;
}
/**
* 打开确认弹窗,并设置相关配置
* @param options ClConfirmOptions 配置项
*/
let timer: number = 0;
function open(options: ClConfirmOptions) {
const next = () => {
// 清除之前的定时器
clearTimeout(timer);
// 设置弹窗状态为打开
closed.value = false;
// 显示弹窗
visible.value = true;
// 设置弹窗标题
config.title = options.title;
// 设置弹窗内容
config.message = options.message;
// 是否显示取消按钮,默认显示
config.showCancel = options.showCancel ?? true;
// 是否显示确认按钮,默认显示
config.showConfirm = options.showConfirm ?? true;
// 取消按钮文本,默认"取消"
config.cancelText = options.cancelText ?? t("取消");
// 确认按钮文本,默认"确定"
config.confirmText = options.confirmText ?? t("确定");
// 显示时长默认0不自动关闭
config.duration = options.duration ?? 0;
// 回调函数
config.callback = options.callback;
// 关闭前钩子
config.beforeClose = options.beforeClose;
// 如果设置了显示时长且不为0则启动自动关闭定时器
if (config.duration != 0) {
// 设置定时器,在指定时长后自动关闭弹窗
// @ts-ignore
timer = setTimeout(() => {
// 调用关闭方法
close();
}, config.duration!);
}
};
if (closed.value) {
next();
} else {
setTimeout(() => {
next();
}, 360);
}
}
// 弹窗关闭后重置loading状态
function onClosed() {
hideLoading();
closed.value = true;
}
/**
* 处理用户操作(确认、取消、关闭)
* @param action ClConfirmAction 操作类型
*/
function onAction(action: ClConfirmAction) {
// 如果没有beforeClose钩子直接关闭并回调
if (config.beforeClose == null) {
visible.value = false;
if (config.callback != null) {
config.callback!(action);
}
} else {
// 有beforeClose钩子时传递操作方法
config.beforeClose!(action, {
close,
showLoading,
hideLoading
});
}
}
defineExpose({
open,
close
});
</script>
<style lang="scss" scoped>
.cl-confirm {
@apply p-4;
&__actions {
@apply flex flex-row items-center justify-center;
}
}
</style>