feat(dialog): 添加关闭事件处理,清理弹窗状态并重置表单数据
This commit is contained in:
parent
fe33c529fd
commit
6244d4db77
@ -4,6 +4,7 @@
|
||||
:title="title"
|
||||
width="500px"
|
||||
destroy-on-close
|
||||
@closed="handleClosed"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
@ -33,6 +34,7 @@
|
||||
:limit="1"
|
||||
:on-error="uploadError"
|
||||
:on-success="uploadSuccess"
|
||||
:on-remove="uploadRemove"
|
||||
class="file-uploader"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
>
|
||||
@ -71,7 +73,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import { nextTick, ref, watch } from 'vue'
|
||||
import { useDict } from '@/utils/dict'
|
||||
import {getToken} from "@/utils/auth.js";
|
||||
import {supportType} from "@/enum/index.js";
|
||||
@ -88,10 +90,10 @@ const props = defineProps({
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['update:visible', 'confirm'])
|
||||
const emit = defineEmits(['update:visible', 'confirm', 'closed'])
|
||||
|
||||
const { ti_function_config } = useDict("ti_function_config");
|
||||
|
||||
@ -140,6 +142,20 @@ const uploadSuccess = (e) => {
|
||||
imgUrl.value = e.msg
|
||||
ElMessage.success('上传成功')
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理已移除图片对应的待提交地址。
|
||||
*
|
||||
* 上传组件只会更新 file-list,不会自动清理独立维护的 imgUrl;如果不处理,用户删除图片后
|
||||
* 确认仍会提交旧地址,因此在列表为空时同步清空。
|
||||
*
|
||||
* @param {*} _uploadFile 被移除的文件
|
||||
* @param {Array} uploadFiles 移除后的文件列表
|
||||
*/
|
||||
const uploadRemove = (_uploadFile, uploadFiles = []) => {
|
||||
if (!uploadFiles.length) imgUrl.value = ''
|
||||
}
|
||||
|
||||
const uploadError = (e) => {
|
||||
console.log("uploadError", e)
|
||||
}
|
||||
@ -156,37 +172,70 @@ const closeViewer = () => {
|
||||
isViewerOpen.value = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按本次打开时的表单数据初始化弹窗私有状态。
|
||||
*
|
||||
* destroy-on-close 只销毁 Dialog 插槽内容,不会销毁当前组件的 ref;因此每次打开都必须同时
|
||||
* 处理“有图片”和“无图片”两种情况,避免编辑记录的上传列表残留到新增记录。
|
||||
*/
|
||||
const syncDialogState = () => {
|
||||
const currentUrl = String(props.formData.iconUrl || '')
|
||||
imgUrl.value = currentUrl
|
||||
uploadFileList.value = currentUrl ? [{
|
||||
name: 'image',
|
||||
url: currentUrl,
|
||||
response: { msg: currentUrl }
|
||||
}] : []
|
||||
uploadFileType.value = null
|
||||
currentImage.value = ''
|
||||
isViewerOpen.value = false
|
||||
nextTick(() => formRef.value?.clearValidate())
|
||||
}
|
||||
|
||||
/**
|
||||
* 在关闭动画结束后清空全部弹窗私有状态,并通知父组件释放共用表单数据。
|
||||
*
|
||||
* 使用 Dialog 的 closed 事件统一覆盖右上角关闭、取消和保存成功,确保所有关闭入口行为一致。
|
||||
*/
|
||||
const handleClosed = () => {
|
||||
imgUrl.value = ''
|
||||
uploadFileList.value = []
|
||||
uploadFileType.value = null
|
||||
currentImage.value = ''
|
||||
isViewerOpen.value = false
|
||||
formRef.value?.clearValidate()
|
||||
emit('closed')
|
||||
}
|
||||
|
||||
watch(() => props.visible, (newVal) => {
|
||||
visible.value = newVal
|
||||
if (props.formData.iconUrl) {
|
||||
imgUrl.value = props.formData.iconUrl
|
||||
uploadFileList.value = [{
|
||||
name: 'image',
|
||||
url: props.formData.iconUrl,
|
||||
response: {
|
||||
msg: props.formData.iconUrl
|
||||
}
|
||||
}]
|
||||
}
|
||||
if (newVal) syncDialogState()
|
||||
})
|
||||
|
||||
watch(visible, (newVal) => {
|
||||
emit('update:visible', newVal)
|
||||
})
|
||||
|
||||
/**
|
||||
* 校验并提交当前表单。
|
||||
*
|
||||
* 校验失败时保留全部输入和上传状态;校验成功后由父组件请求接口,只有父组件关闭弹窗时
|
||||
* 才统一执行清理,避免接口响应前图片列表提前消失。
|
||||
*/
|
||||
function handleConfirm() {
|
||||
if (!formRef.value) return
|
||||
|
||||
formRef.value.validate((valid) => {
|
||||
if (!valid) return
|
||||
const obj = { ...props.formData }
|
||||
if (imgUrl.value && imgUrl.value.length > 0) {
|
||||
obj.iconUrl = imgUrl.value
|
||||
}
|
||||
uploadFileList.value = []
|
||||
emit('confirm', valid, { ...obj })
|
||||
obj.iconUrl = imgUrl.value || null
|
||||
emit('confirm', true, { ...obj })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭弹窗;具体状态清理由 closed 事件统一处理,避免不同关闭入口遗漏字段。
|
||||
*/
|
||||
function handleCancel() {
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
@ -86,6 +86,7 @@
|
||||
:title="functionDialogTitle"
|
||||
:form-data="functionFormData"
|
||||
@confirm="handleFunctionConfirm"
|
||||
@closed="handleFunctionDialogClosed"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@ -140,7 +141,22 @@ function handleReset() {
|
||||
|
||||
const isAdd = ref(true)
|
||||
|
||||
// 新增功能
|
||||
/**
|
||||
* 重置新增、编辑共用的功能表单。
|
||||
*
|
||||
* 表单对象由父组件持有,子弹窗的 destroy-on-close 不会释放它;集中重置可确保关闭编辑弹窗后
|
||||
* 再次新增时不会携带上一条记录的数据。
|
||||
*/
|
||||
function resetFunctionFormData() {
|
||||
functionFormData.funcKey = ''
|
||||
functionFormData.remark = ''
|
||||
functionFormData.id = null
|
||||
functionFormData.iconUrl = null
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开新增功能弹窗,并确保起始表单为空。
|
||||
*/
|
||||
function handleAddFunction() {
|
||||
if (props.selectNode?.type !== 'version') {
|
||||
ElMessage.warning('请先选择车机版本')
|
||||
@ -148,13 +164,21 @@ function handleAddFunction() {
|
||||
}
|
||||
isAdd.value = true
|
||||
functionDialogTitle.value = '新增功能'
|
||||
functionFormData.funcKey = ''
|
||||
functionFormData.remark = ''
|
||||
functionFormData.iconUrl = null
|
||||
functionFormData.id = null
|
||||
resetFunctionFormData()
|
||||
functionDialogVisible.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应弹窗完全关闭,释放父组件持有的表单状态。
|
||||
*
|
||||
* 该入口同时覆盖取消、右上角关闭和保存成功,避免只清理某一种关闭路径。
|
||||
*/
|
||||
function handleFunctionDialogClosed() {
|
||||
resetFunctionFormData()
|
||||
functionDialogTitle.value = ''
|
||||
isAdd.value = true
|
||||
}
|
||||
|
||||
// 确认功能操作
|
||||
async function handleFunctionConfirm(valid, data) {
|
||||
if (valid) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user