Files
Docker/uniapp/youjiala/src/components/folder-name-dialog/folder-name-dialog.vue
T
2026-10-15 13:08:28 +08:00

165 lines
4.3 KiB
Vue
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.
<script setup lang="ts">
/**
* 命名对话框(新建文件夹 / 重命名共用):居中卡片(标题 + 输入 + 取消/确认)。
* 只负责收集名称——非法字符校验、接口与结果提示由页面分流。
* 新建态不传 title/confirmLabel 走默认「新建文件夹/创建」;重命名态由页面传入并预填 initialValue。
* 提交成功后由父级收起 visible;submitting 期间禁用按钮防连点。
*/
import { useLocale } from "uview-pro";
import { computed, ref, watch } from "vue";
const props = defineProps({
/** 对话框是否展开 */
visible: {
type: Boolean,
default: false,
},
/** 创建/重命名请求在途:置灰两个按钮 */
submitting: {
type: Boolean,
default: false,
},
/** 标题文案,默认「新建文件夹」 */
title: {
type: String,
default: "",
},
/** 确认按钮文案,默认「创建」 */
confirmLabel: {
type: String,
default: "",
},
/** 展开时预填的名称(重命名带当前名),空则清空输入 */
initialValue: {
type: String,
default: "",
},
/** 输入框占位文案:缺省沿用「新建文件夹」语义,群描述/申请原因等场景由页面覆写 */
placeholder: {
type: String,
default: "",
},
});
const emit = defineEmits<{
/** 取消/遮罩关闭 */
(e: "close"): void;
/** 点了创建且名称非空 */
(e: "confirm", name: string): void;
}>();
const { t } = useLocale();
const name = ref("");
/** 空白名不算可提交 */
const canSubmit = computed(() => name.value.trim().length > 0);
// 每次展开按 initialValue 预填(重命名带当前名、新建为空),聚焦即全选方便改(对话框实例常驻 tab 页)
watch(
() => props.visible,
(on) => {
if (on) {
name.value = props.initialValue || "";
}
},
);
function onConfirm(): void {
if (!props.submitting && canSubmit.value) {
emit("confirm", name.value.trim());
}
}
</script>
<template>
<!-- u-popup 只认 modelValue(v-model);提交中禁点遮罩防误关 -->
<u-popup :model-value="props.visible" mode="center" round="24" :close-on-click-overlay="!props.submitting"
@close="emit('close')">
<view class="folder-name-dialog">
<text class="folder-name-dialog__title">
{{ props.title || t("FilePage.addFolder") }}
</text>
<input v-model="name" class="folder-name-dialog__input"
:placeholder="props.placeholder || t('FilePage.folderPlaceholder')" :maxlength="50" :disabled="props.submitting"
confirm-type="done" @confirm="onConfirm">
<view class="folder-name-dialog__actions">
<view class="folder-name-dialog__btn" @click="emit('close')">
<text class="folder-name-dialog__btn-text">
{{ t("FilePage.folderCancel") }}
</text>
</view>
<view class="folder-name-dialog__btn folder-name-dialog__btn--primary"
:class="{ 'folder-name-dialog__btn--muted': !canSubmit || props.submitting }" @click="onConfirm">
<text class="folder-name-dialog__btn-text folder-name-dialog__btn-text--primary">
{{ props.confirmLabel || t("FilePage.folderConfirm") }}
</text>
</view>
</view>
</view>
</u-popup>
</template>
<style lang="scss" scoped>
.folder-name-dialog {
width: 560rpx;
padding: 40rpx 32rpx 32rpx;
background-color: #ffffff;
&__title {
display: block;
padding-bottom: 28rpx;
font-size: 32rpx;
font-weight: 600;
color: #1f2329;
text-align: center;
}
&__input {
box-sizing: border-box;
width: 100%;
height: 80rpx;
padding: 0 24rpx;
border: 2rpx solid #e6e7ea;
border-radius: 16rpx;
font-size: 28rpx;
color: #1f2329;
background-color: #f7f8fa;
}
&__actions {
display: flex;
gap: 20rpx;
margin-top: 32rpx;
}
&__btn {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
height: 76rpx;
border-radius: 999rpx;
background-color: #f5f6f8;
&--primary {
background-color: #2b8fff;
}
/* 名称为空或提交中:主按钮置灰(仍可点,由 onConfirm 拦截) */
&--muted {
background-color: #b9d6ff;
}
}
&__btn-text {
font-size: 28rpx;
color: #5c626b;
&--primary {
color: #ffffff;
}
}
}
</style>