Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
July 10, 2021 05:52 pm GMT

How to register global components in Vue 3 dynamically?

Header image above is a screenshot from the official website of Vue 3.

Vue 3 is now stable since June 8, 2021 with version 3.1.0 named Pluto. It is Typescript compatible and introduces Composition API where you can initialize most parts of the component inside the setup function. If you want more info about Vue 3, you can check the links below:

Let's immediately proceed with the topic of this article. Vue 3 already has a documentation about registering components globally. Global components are Vue components that can be declared immediately inside the template of another component without import and declaration in components property. If you're not familiar with Vue 3, this is how we import other components inside a component:

<template>    <div>        <SomeComponent/>    </div></template><script lang="ts">import { defineComponent } from 'vue';import SomeComponent from '@/components/SomeComponent.vue';export default defineComponent({    components: { SomeComponent },});</script>

Assuming the file above is inside the views directory and we're importing a reusable component from the components directory. As you can see that it's not different on how we import components in Vue 2 except the difference in creating a component and the usage of Typescript (by adding lang="ts" inside the script tag).

If we make the component globally accessible to other components, this will be very helpful when our project becomes big making it more reusable. It will also remove the import of multiple components inside a component unless the component is a local sub-component. See example below:

<template>    <div>        <SomeComponent/>    </div></template><script lang="ts">import { defineComponent } from 'vue';export default defineComponent({});</script>

As you can see we just declared the SomeComponent component like a HTML element directly inside of another component without the import syntax and the components parameter inside the defineComponent function.

So how do we make a global component in Vue 3? According to the official documentation, here's how we register a component globally in main.ts file if you're developing using Typescript else in main.js file:

import { createApp } from 'vue';import ComponentC from './components/ComponentC.vue';// Usually it is App.vue inside the createApp function.// App.vue is your main or root Vue component.const app = createApp({}); // Component named with kebab-case.app.component('component-a', {  /* ... */});// Component named with PascalCase.app.component('ComponentB', {  /* ... */});app.component('ComponentC', ComponentC);// The second argument of the component function is the object that creates a component or it can be an imported component instance.// It willl mount the Vue app inside the HTML element with ID of // #app in index.html which is located in public directory.app.mount('#app');

Reference: Vue 3 Global Registration

If we follow the procedure above, it will bloat our main.js or main.ts file especially if our application becomes bigger then our reusable components will increase. So how do we prevent that from happening?

I actually got the idea from Vue 2 documentation on registering global components dynamically which I always use when developing a frontend application using Vue 2. In Vue 3, they don't have this section in their documentation.

Reference: Automatic Global Registration of Base Components

Here's my implementation:

./components/base/index.ts

import { App } from 'vue';const requireComponent = require.context(  // The relative path of the components folder  './',  // Whether or not to look in subfolders  false,  // The regular expression used to match base component filenames  /[A-Z]\w+Base\.vue$/,);const register = (app: App<Element>): void => {  requireComponent.keys().forEach((fileName) => {    // Get component config    const componentConfig = requireComponent(fileName);    // Get component name    const componentName = fileName.split('/').pop()?.replace(/\.\w+$/, '') as string;    app.component(componentName, componentConfig.default || componentConfig);  });};export default {  register,};

If you checked the link I gave above for Vue 2 implementation, it is almost the same as my implementation above for Vue 3. Here are the differences in my implementation:

  • I have an argument of app with type of App<Element>. App type is from vue package and the Element type is more of an interface. See more details here.
  • My relative path is './' because I placed this code in ./components/base/index.ts.
  • My regex will get all the files that ends in Base.vue for them to be considered as a global component. I prefer to place all global components inside the base directory but you can name it anything you prefer.
    • e.g. GlobalComponentBase.vue
  • I didn't used the lodash package if you prefer minimum external packages.

Here's how I implemented it in the main.ts file:

main.ts

import { createApp } from 'vue';import BaseComponents from './components/base';const app = createApp(App);BaseComponents.register(app);app.mount('#app');

That's it! Your main file will not bloat when you have hundreds of global components to register. I hope this article will help you a lot.

I also created a Github Gist of the code implementation above:
https://gist.github.com/jirehnimes/2fcb31a2cbe7bb0c722a96f49e4cbf8f

Cheers!


Original Link: https://dev.to/jirehnimes/how-to-register-global-components-in-vue-3-dynamically-3gl

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To