I have a simple app. Clicking to [new item] links opens a child component which has a modal window component for user input.
What is the best way to open modal from the App component. I am not also sure this design is the best approach. I used to manage this with Classes and Methods when I was using native js. But in VUE accessing sub components methods via an interface is a pain. All I want to do is to open a new item model anywhere in the app.
Structure:
|--App.vue
| |--NewItem.vue
| | |--Modal.vue
App.vue:
<template>
<a @click="openNewItem()"> + NEW ITEM</a>
...
<a @click="openNewItem()"> + NEW ITEM</a>
...
//Create new Item link appears at multiple places in app
<NewItem />
</template>
<script setup>
conts openNewItem=()=>{
//....
}
</script>
NewItem.vue:
<template>
<Modal v-model:visible="dialogOpen">
<template v-slot:title>New Item</template>
<template v-slot:content >
<input type="text" class="lg" />
<button @click="create()">ADD ITEM</button>
</template>
</Modal>
</template>
<script setup>
import { ref} from "vue";
import Modal from "./Modal.vue";
const dialogOpen=ref(false);
const create=()=>{
//logic...
console.log("create item");
//close modal...
dialogOpen.value=false
}
</script>
Modal.vue:
<template >
<template v-if="isVisible" >
<div class="overlay"><!-- overlay --></div>
<section>
<div class="main" v-bind="$attrs" >
<div class="head">
<div class="title">
<slot name="title"></slot>
</div>
<div>
<a @click="close()">✖</a>
</div>
</div>
<div class="content">
<slot name="content"></slot>
</div>
</div>
</section>
</template>
</template>
<script setup>
import { computed } from "vue";
const props = defineProps({
visible: Boolean
});
const emit = defineEmits(["update:visible"]);
const isVisible = computed({
get: () => props.visible,
set: (value) => {
emit("update:visible", value);
},
});
const close = () => {
isVisible.value = false
}
</script>