101 lines
1.9 KiB
Vue
101 lines
1.9 KiB
Vue
|
|
<template>
|
||
|
|
<el-drawer
|
||
|
|
:visible.sync="visible"
|
||
|
|
:title="title"
|
||
|
|
:size="size"
|
||
|
|
:direction="direction"
|
||
|
|
destroy-on-close
|
||
|
|
>
|
||
|
|
<component
|
||
|
|
v-if="dynamicComponent"
|
||
|
|
:is="dynamicComponent"
|
||
|
|
ref="dynamicComponentRef"
|
||
|
|
v-bind="componentProps"
|
||
|
|
@vue:mounted="handleComponentMount"
|
||
|
|
/>
|
||
|
|
|
||
|
|
<template #footer>
|
||
|
|
<div class="drawer-footer">
|
||
|
|
<el-button @click="onCancel">取消</el-button>
|
||
|
|
<el-button type="primary" @click="onConfirm">确认</el-button>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
</el-drawer>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup>
|
||
|
|
import { computed, ref, markRaw } from "vue";
|
||
|
|
|
||
|
|
const dynamicComponentRef = ref(null);
|
||
|
|
defineExpose({
|
||
|
|
dynamicComponentRef,
|
||
|
|
});
|
||
|
|
|
||
|
|
const props = defineProps({
|
||
|
|
visible: {
|
||
|
|
type: Boolean,
|
||
|
|
default: false,
|
||
|
|
},
|
||
|
|
size: {
|
||
|
|
type: String,
|
||
|
|
default: "50%",
|
||
|
|
},
|
||
|
|
direction: {
|
||
|
|
type: String,
|
||
|
|
default: "rtl", // rtl/ltr/ttb/btt
|
||
|
|
validator: (v) => ["rtl", "ltr", "ttb", "btt"].includes(v),
|
||
|
|
},
|
||
|
|
title: {
|
||
|
|
type: String,
|
||
|
|
default: "",
|
||
|
|
},
|
||
|
|
dynamicComponent: {
|
||
|
|
type: [Object, Function],
|
||
|
|
default: null,
|
||
|
|
},
|
||
|
|
componentProps: {
|
||
|
|
type: Object,
|
||
|
|
default: () => ({}),
|
||
|
|
},
|
||
|
|
onConfirm: {
|
||
|
|
type: Function,
|
||
|
|
default: () => {},
|
||
|
|
},
|
||
|
|
onCancel: {
|
||
|
|
type: Function,
|
||
|
|
default: () => {},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
const emit = defineEmits(["update:visible"]);
|
||
|
|
|
||
|
|
// 状态同步
|
||
|
|
const normalizedComponent = computed(() =>
|
||
|
|
props.dynamicComponent ? markRaw(props.dynamicComponent) : null
|
||
|
|
);
|
||
|
|
|
||
|
|
// 关闭处理
|
||
|
|
const handleClose = () => {
|
||
|
|
emit("update:visible", false);
|
||
|
|
};
|
||
|
|
|
||
|
|
// 确认/取消时自动关闭
|
||
|
|
const onConfirm = () => {
|
||
|
|
props.onConfirm();
|
||
|
|
handleClose();
|
||
|
|
};
|
||
|
|
|
||
|
|
const onCancel = () => {
|
||
|
|
props.onCancel();
|
||
|
|
handleClose();
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.drawer-footer {
|
||
|
|
display: flex;
|
||
|
|
justify-content: flex-end;
|
||
|
|
gap: 12px;
|
||
|
|
}
|
||
|
|
</style>
|