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