Low-level implementation of the full life cycle of a component in Vue 2

The article will focus on the low-level implementation of the component’s life cycle: declaration, mounting in the DOM, destroying an instance of the component itself.

We are used to the most common use of components: declaration, registration, accessing a component from another with passing parameters. We describe the component in the componentName.vue file and call it in the template of another component as But what if we want to call, say, a dialog box from the plugin? And we want the whole application not to know about our dialog box, but only the plug-in? It was with such a task that I encountered on a working project and I had to collect information bit by bit. I’ll tell you how all of the above was implemented. I did it in a plugin, but it’s not required. This approach can be implemented in the project itself.

Development environment:

  • vue: 2

  • Nuxt: ^2.15

  • Vuetify: ^2.6

Global component registration.

Inside my notification plugin, I register the simplest possible component – a dialog box with the type passed to the plugin, a message and a close button. The type determines what color the message is. Classical: success, info, error, warning. The dialog close button will debuild the component instance and remove it from the DOM. My component will have almost no logic – only a template. Therefore, the render function immediately goes into the component. Its task is to return the html code of the component.

   let Nf = Vue.component('notificationDialog', {

        render: function (createElement) {

	 }

})

There is good documentation on the function, I will not stop.

Next, we describe the nesting of html tags using createElement

const alertVNode = createElement('v-alert', {

     attrs: { type: message.type, icon: false }, // атрибуты

    style: {	// стили элемента

        width: '100%'

        }

    },

    message.text) // содержимое: String или Array<VNodes>

const cardVNode = createElement('v-card', {

    class: ['pa-2', 'd-flex', 'flex-column', 'align-end',]

    },

    [alertVNode]) // Предыдущий узел добавляется как дочерний в карточку

Who noticed something unusual, well done. Yes! createElement understands Vuetify tags. This is great, because saves time writing nested tags and styles for them! One more thing. For the same reason, you can change styles to classes that are relevant to them. An example is below.

 const cardDivVNode = createElement('v-card', {

     style:{

		padding: ‘8px’,

		display: ‘flex’,

		flexDirection: ‘column’,

		alignItems: ‘end’

     },

    class: ['pa-2', 'd-flex', 'flex-column', 'align-end',]

})

What you see in the style and class objects in the example above are the same. So padding: ‘8px’ is the same as replacing it with ‘pa-2’. It stands for ‘padding all = 2*4px’. Therefore, for a uniform design, I use Vuetify classes where possible:

const cardDivVNode = createElement('v-card', {

    class: ['pa-2', 'd-flex', 'flex-column', 'align-end',]

})

Mounting the Component Instance and Adding it to the DOM

The component is declared. Next, in the plugin logic we:

  • create an instance of the class

  • mount it in DOM

  • and add as a child of our root element with id=”app”

    let component = new Nf() 	// создаем экземпляр класса

    component.$mount()		// монтируем его в DOM

    document.getElementById('app')?.appendChild(component.$el) // добавляем в корень

At this stage, everything.

Destroy component instance, remove from DOM

As mentioned above, the component instance will debuild itself. In the template of the notificationDialog component, in render function there is a button to close the dialog box:

const closeButtonVNode = createElement('v-btn', {

        attrs: {

            outlined: true, // аттрибуты Vuetify

            color: 'primary',

            block: false,

            inline: true

        },

        on: {

        // события размещаются тут

        }

}, 'Close')

She will have an onClick method:

const closeButtonVNode = createElement('v-btn', {

        …

        on: {

            click: () => {

                this.$destroy() // дестроим текущий экземпляр

                this.$el?.parentNode?.removeChild(this.$el) // удаляем из DOM

            }

            }

        }, 'Close')

Conclusion

We managed to create a notificationDialog component in a plugin that the main application does not know about.

  • The component is declared globally – once, when building the application

  • Instances are created when the plugin is called

  • Instances destroy themselves at the push of a button.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *