Yes, this is a somewhat irritating behavior of Vue, where refs in the template are not unwrapped when they come from an array or object (see this bug for reference). You will have to unwrap it yourself, i.e. write modals.add_directory.value
:
<v-dialog v-model="modals.add_directory.value">
...
</v-dialog>
You can see it working like that in the snippet:
const { createApp, ref } = Vue;
const { createVuetify } = Vuetify
const vuetify = createVuetify()
const app = {
setup(){
const modals = {
addDirectory: ref(false),
};
const openModal = (modalName) => {
modals[modalName].value = !modals[modalName].value;
};
return { openModal, modals }
}
}
createApp(app).use(vuetify).mount('#app')
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/vuetify@3.1.8/dist/vuetify.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/vuetify@3.1.8/dist/vuetify-labs.min.css" />
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<v-dialog v-model="modals.addDirectory.value">
<v-card>
<v-card-title>
The add directory dialog
</v-card-title>
</v-card>
</v-dialog>
<v-btn @click="openModal('addDirectory')" class="ma-4">
add directory
</v-btn>
</v-main>
</v-app>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@3.1.8/dist/vuetify.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@3.1.8/dist/vuetify-labs.js"></script>
Alternatively, you could use reactive
, which does not have this limitation:
const modals = reactive({
addDirectory: false,
});
const openModal = (modalName) => {
modals[modalName] = !modals[modalName];
};
const { createApp, reactive } = Vue;
const { createVuetify } = Vuetify
const vuetify = createVuetify()
const app = {
setup(){
const modals = reactive({
addDirectory: false,
});
const openModal = (modalName) => {
modals[modalName] = !modals[modalName];
};
return { openModal, modals }
}
}
createApp(app).use(vuetify).mount('#app')
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/vuetify@3.1.8/dist/vuetify.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/vuetify@3.1.8/dist/vuetify-labs.min.css" />
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<v-dialog v-model="modals.addDirectory">
<v-card>
<v-card-title>
The add directory dialog
</v-card-title>
</v-card>
</v-dialog>
<v-btn @click="openModal('addDirectory')" class="ma-4">
add directory
</v-btn>
</v-main>
</v-app>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@3.1.8/dist/vuetify.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@3.1.8/dist/vuetify-labs.js"></script>
Does that work for you?