Files
web/app/components/Modal2.vue
2026-05-07 10:53:59 +07:00

98 lines
2.5 KiB
Vue

<script setup>
const props = defineProps({
id: String,
component: String,
title: String,
width: String,
height: String,
vbind: Object,
onClose: Function,
onEvent: Function,
});
const componentFiles = import.meta.glob("@/components/**/*.vue");
const resolvedComponent = shallowRef(null);
function loadDynamicComponent() {
if (!props.component) {
resolvedComponent.value = null;
return;
}
const fullPath = `/components/${props.component}.vue`;
const componentPath = Object.keys(componentFiles).find((path) => path.endsWith(fullPath));
if (componentPath) {
resolvedComponent.value = defineAsyncComponent(componentFiles[componentPath]);
} else {
console.error(`Không tìm thấy component tại: ${fullPath}`);
resolvedComponent.value = null;
}
}
// Theo dõi sự thay đổi của props.component để load lại nếu cần
watchEffect(() => {
loadDynamicComponent();
});
const handleEvent = (id, eventName, data) => props.onEvent(id, eventName, data);
</script>
<template>
<div>
<div
:id="id"
class="modal is-active has-text-text-20"
@click="
(e) => {
if (e.target.classList.contains('modal-background')) props.onClose(id);
}
"
>
<div class="modal-background"></div>
<div
class="modal-card"
:style="{
// width: $store.viewport <= 2 ? 'calc(100% - 2rem)' : width || '60%',
}"
>
<header
v-if="title"
class="modal-card-head px-4 py-3"
>
<div class="w-full">
<div class="field is-grouped is-align-items-center">
<div class="control is-expanded has-text-left">
<p
class="fs-17 font-semibold has-text-primary"
v-html="title"
></p>
</div>
<div class="control has-text-right">
<button
class="delete is-medium"
@click="onClose(id)"
></button>
</div>
</div>
</div>
</header>
<section
class="modal-card-body p-4"
:style="{
minHeight: height || '750px',
}"
>
<component
:is="resolvedComponent"
v-bind="vbind"
@close="onClose(id)"
@event="(e) => handleEvent(id, e.name, e.data)"
/>
</section>
<footer class="modal-card-foot pt-0 px-4 pb-4"></footer>
</div>
</div>
</div>
</template>