Tengo un componente personalizado que básicamente es un componente v-btn con un estilo específico. Cuando lo uso dentro del activador de menú v con condicional basado en el punto de interrupción de visualización, el componente personalizado no se muestra en la pantalla. Pero si uso v-btn regular, el botón se muestra correctamente según el punto de interrupción de la pantalla. ¿Qué estoy haciendo mal aquí?
https://codepen.io/jgunawan-dc/pen/XWzJqRy?editors=1010
<div id="app"> <v-app id="inspire"> <div class="text-center"> <v-menu offset-y> <template v-slot:activator="{ on, attrs }"> <global-custom-button v-if="$vuetify.breakpoint.mdAndDown" v-bind="attrs" v-on="on" > Show on medium and lower </global-custom-button> <v-btn v-else color="primary" dark v-bind="attrs" v-on="on" > Dropdown </v-btn> </template> <v-list> <v-list-item v-for="(item, index) in items" :key="index" > <v-list-item-title>{{ item.title }}</v-list-item-title> </v-list-item> </v-list> </v-menu> </div> </v-app> </div> Vue.component('global-custom-button', { template: '<v-btn outlined color="info" @click="$emit(\'click\', $event)"><slot></slot></v-btn>' }); new Vue({ el: '#app', vuetify: new Vuetify(), data: () => ({ items: [ { title: 'Click Me' }, { title: 'Click Me' }, { title: 'Click Me' }, { title: 'Click Me 2' }, ], }), })Hay dos errores que surgen del escenario anterior:
Mensaje de error 1:
[Vue warn]: Error in nextTick: "NotFoundError: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node."Mensaje de error 2:
DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.Esto surge cuando Vue intenta insertar un elemento antes de otro, pero el elemento ya no existe en el DOM.
En su caso, parece que cambiar $vuetify.breakpoint.mdAndDown de verdadero a falso o viceversa limpia el componente global-custom-button o el Dropdown v-btn .
Una posible solución sería usar v-show en lugar de v-if .
Una advertencia:
Tenga en cuenta que v-show no es compatible con el elemento ni funciona con v-else.
Así que esta sugerencia puede funcionar (puede cambiar para satisfacer sus necesidades):
<global-custom-button v-show="$vuetify.breakpoint.mdAndDown" v-bind="attrs" v-on="on" > Show on medium and lower </global-custom-button> <v-btn v-show="!$vuetify.breakpoint.mdAndDown" color="primary" dark v-bind="attrs" v-on="on" > Dropdown </v-btn>EDITAR:
Esto funciona sin v-if o v-show
Para una solución rápida, use v-show como dijo @Rotiken.
Como otra solución, también podría registrar dos componentes globales y mostrarlos/ocultarlos usando una condition adicional:
<v-menu offset-y> <template v-slot:activator="{ on, attrs }"> <global-custom-button :condition="$vuetify.breakpoint.mdAndDown" v-bind="attrs" v-on="on" > Show on medium and lower </global-custom-button> <global-custom-button-2 :condition="!$vuetify.breakpoint.mdAndDown" v-bind="attrs" v-on="on" > Dropdown </global-custom-button-2> </template> ... </v-menu> ... Vue.component('global-custom-button', { template: '<v-btn v-if="condition" outlined color="info" @click="$emit(\'click\', $event)"><slot></slot></v-btn>', props: ['condition'] }); Vue.component('global-custom-button-2', { template: '<v-btn v-if="condition" color="primary" dark @click="$emit(\'click\', $event)"><slot></slot></v-btn>', props: ['condition'] }); ...Según este CodePen , esto también funciona.
Por qué sucede esto y por qué v-show funciona bien con la misma plantilla: no puedo dar una respuesta exacta, pero hay algunas suposiciones.
Los documentos de Vue.js dicen que v-if elimina objetos de DOM, mientras que v-show cambia su estado de visualización en CSS, pero lo mantiene en DOM.
Dado que está utilizando v-if en un componente v-menu vuetify, tal vez el componente tenga algunos métodos para actualizar el contenido v-slot:activator que puede entrar en conflicto (y no se realiza al mismo tiempo) con la representación condicional usando v-if y Vuetificar puntos de interrupción de visualización.
Si está familiarizado con TypeScript, puede buscar fuentes de menú v o fuentes de mezclas activables . Quizás aquí encuentres la verdadera razón de este comportamiento.
Si solo quiere evitar tales problemas, use v-show en tales casos.