Inject nuxt.config.js configuration into globally registered component using custom built Nuxt module

1.2k Views Asked by At

So this question might be quite complicated, but I'll try to explain it as clear as I can.

I am currently in the process of creating a Nuxt Module. If you're familiar with creating them you know it's possible to configure it in your nuxt.config.js. Which I have done right here:

components: {
    modules: ['carousel', 'filter', 'post-loop', 'gform'],
    gform: {
         title: true
    }
},

I have an array of modules that I would like to globally register. I have done so using the following configuration:

(index.js)

const path = require('path');

export default function ClassName(moduleOptions) {

    const options = Object.assign({}, this.options.components, moduleOptions);
    const availableModules = ['carousel', 'filter', 'gform', 'post-loop'];
    const unknownModules = options.modules.filter(mod => !availableModules.includes(mod));

    if(!options.modules) {
        throw new Error('ERROR: Please check the ReadMe, you need to include a modules array specifying what modules you want to enable');
    }

    if(unknownModules.length > 0) {
        throw new Error(`ERROR: The following modules do not exist in the @blueelevation/components module: ${unknownModules}`);
    }

    this.addPlugin({
        src: path.resolve(__dirname, './plugin/plugin.js'),
        options: options
    })

    const cssFilesToLoad = ['carousel.css'];

    cssFilesToLoad.forEach(file => this.options.css.push(path.resolve(__dirname, `dist/css/${file}`)));

    this.addPlugin({
        src: path.resolve(__dirname, './plugin/eventbus.js'),
    })
}

The important part to focus on is the plugin.js in which I register the components globally in the Nuxt instance:

import Vue from 'vue';

/**
 * If the module array contains carousel, we register it as a global component.
 */
<% if(options.modules.includes('carousel')) { %>
    import Carousel from '@blueelevation/components/components/Carousel/Carousel.vue';
    Vue.component('Carousel', Carousel);
<% } %>

/**
 * If the module array contains post-loop, we register it as a global component.
 */
<% if(options.modules.includes('post-loop')) { %>
    import PostLoop from '@blueelevation/components/components/PostLoop/PostLoop.vue';
    Vue.component('pwa-post-loop', PostLoop);
<% } %>

/**
 * If the module array contains filter, we register it as a global component.
 */
<% if(options.modules.includes('filter')) { %>
    import Filter from '@blueelevation/components/components/Filter/Filter.vue';
    import FilterHeading from '@blueelevation/components/components/Filter/FilterHeading.vue';
    Vue.component('pwa-filter', Filter);
    Vue.component('pwa-filter-heading', FilterHeading);
<% } %>

/**
 * If the module array contains gform, we register it as a global component.
 */
<% if(options.modules.includes('gform')) { %>
    import GForm from '@blueelevation/components/components/GForm/GForm.vue';
    Vue.component('pwa-gform', GForm);
<% } %>

As you can see I register the component globally in case it is specified in the array. The part where I'm currently stuck on is that I have a gform.title property in my nuxt.config.js. How do I pass this Boolean to the globally registered GForm component? So I can conditionally render the title in case it's true?

1

There are 1 best solutions below

3
On BEST ANSWER

I answered my own question. If somebody every wonders how to do it, you can inject something into your component(s) by doing the following in plugin.js:

import Vue from 'vue';
import Carousel from '@blueelevation/components/components/Carousel/Carousel.vue';
import PostLoop from '@blueelevation/components/components/PostLoop/PostLoop.vue';
import Filter from '@blueelevation/components/components/Filter/Filter.vue';
import FilterHeading from '@blueelevation/components/components/Filter/FilterHeading.vue';
import GForm from '@blueelevation/components/components/GForm/GForm.vue';

    export default(context, inject) => {
    /**
     * If the module array contains carousel, we register it as a global component.
     */
    <% if(options.modules.includes('carousel')) { %>
        Vue.component('Carousel', Carousel);
    <% } %>

    /**
     * If the module array contains post-loop, we register it as a global component.
     */
    <% if(options.modules.includes('post-loop')) { %>
        Vue.component('pwa-post-loop', PostLoop);
    <% } %>

    /**
     * If the module array contains filter, we register it as a global component.
     */
    <% if(options.modules.includes('filter')) { %>
        Vue.component('pwa-filter', Filter);
        Vue.component('pwa-filter-heading', FilterHeading);
    <% } %>

    /**
     * If the module array contains gform, we register it as a global component.
     */
    <% if(options.modules.includes('gform')) { %>
        Vue.component('pwa-gform', GForm);
        inject('GForm', {config: <%= serialize(options.gform) %> });
    <% } %>
}

Note the inject() function underneath the global registration of the gform component. I inject GForm with a serialized object (options.gform as seen in the nuxt.config.js). Afterwards this GForm config will be available in the component through:

this.$GForm.config.

Hope this helps somebody in the future.