I’ve finally been able to encapsulate a Vuetify <v-dialog>
in a custom component in Vue 3 Composition API. Below is the code for my SignUpDialog.vue
component. It’s also available in a Vuetify Play playground.
<script setup>
import { onMounted } from 'vue'
const props = defineProps({ modelValue: Boolean })
const emits = defineEmits(['update:modelValue'])
function updateModelValue(value) {
emits('update:modelValue', value)
}
onMounted(() => {
/* Verbose code that initializes firebase ui auth....*/
// ui.start('#firebaseui-auth-container', uiConfig)
/* Fails with error: "Could not find the FirebaseUI widget element on the page." */
})
</script>
<template>
<h3>modelValue: {{ modelValue }}</h3>
<v-dialog :model-value="modelValue" @update:model-value="updateModelValue">
<v-sheet class="mx-auto">
<v-card>
<v-card-title>modelValue: {{ modelValue }}</v-card-title>
<div id="firebaseui-auth-container"></div>
</v-card>
</v-sheet>
</v-dialog>
</template>
<style scoped></style>
<script></script>
My goal now is to populate the dialog with content from FirebaseUI’s Auth SDK. I’m not including the actual code here because it’s rather verbose. Suffice it to say that it ends with a call to an SDK function that injects HTML into <div id="firebaseui-auth-container"></div>
.
I’ve tried running the initialization code in the onMounted
event handler and that yields an error that says:
Could not find the FirebaseUI widget element on the page.
I think this is because the dialog is hidden at the time the custom component is mounted and so the <div>
does not exist in the DOM yet.
My question is – How can I use idiomatic Vue 3 Composition API to have the initialization code run as soon as the <v-dialog>
is rendered so that it succeeds in injecting into the <div>
?
2
Answers
A watcher sounds appropriate here. It can run code only once the dialog is rendered, which would be when
modelValue
is true, so you would watch that value. I’m not familiar with the firebase SDK but in case it only needs to run once you can include a flag variable, e.g.initialized
that can be used in anif
to only run the code one time.You could use VNode hook
@vue:mounted
on the element then use the handler to init the Firebase widget: