On va-card, va-modal and encapsulation (sort of) #3856
Closed
KazimirPodolski
started this conversation in
General
Replies: 1 comment
-
We can provide a slot to replace default card. But for now you can use content slot and change va-modal__inner layout. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I think Vuestic should rework Card and Modal and copy Vuetify's approach instead of classic approach to modals.
In Vuetify modal does not impose any structure on it's internals, it's literally just "modal" content which raises user's attention and covers other content. With a card inside modal you get classic modal dialog structure with big title first, content, action buttons last. Best thing about it is that it promotes reusable and encapsulated element, e.g. a user form - the element manages impl. details for everything about creating a user.
How would I make a user form in a modal in Vuetify? Probably like this:
<!-- User form component --> <script setup> ... // encapsulated! a form knows how to save itself and does it const submit = () => { saveForm(); emit('done'); }; </script> <template> <v-card> <template #title> New User </template> <template #text> <v-form @submit.prevent="submit"> <!-- form fields --> </v-form> </template> <template #actions> <v-btn @click="emit('done')">Cancel</v-btn> <v-btn type="submit">Submit</v-btn> </template> </v-card> </template> <!-- New user modal somewhere where you need it --> <template> ... <v-dialog v-model="userForm"> <UserForm @done="() => userForm = false"/> <!-- not form, nor parent component knows anything about user form --> <template #activator="{props}"> <v-btn v-bind="props">Create User</v-btn> </template> </v-dialog> ... </template>
Vuestic follows classic approach when a modal has actions and defines them itself. I think usually it looks like this:
<!-- User form component --> <script setup> ... // if form knows how to submit, then it needs an emit from parent to do so (on Save button or else) - bad practice! </script> <template> <va-form> <!-- form fields --> </va-form> </template> <!-- New user modal somewhere where you need it --> <script setup> const user = ref(...); // breaks encapsulation! const saveUser = ...; // breaks encapsulation! // good only if it comes from a composable coupled with user form, but that is not KISS at all </script> <template> ... <va-modal v-model="userForm"> <UserForm v-model="user"/> <template #header> New User </template> <template #footer> <va-button @click="saveUser(user)"> </template> </v-dialog> ... </template>
I don't see the option which is at the same time reusable (being a modal breaks reusability! One cannot assume user form will always be in a modal), encapsulated (form state and methods should not leak to parent), and not doing some nasty Vue practices like sending events from parent modal to trigger child's submit.
There is a way to still make it with va-modal and va-card by tweaking styles, but my point is the better structure should be the default and the obvious way.
BTW both va-card and va-modal feels quite vue2, even react vibes from modal's callbacks (why not events?).
Beta Was this translation helpful? Give feedback.
All reactions