loading...

re: Dynamic components using VueJS VIEW POST

TOP OF THREAD FULL DISCUSSION
re: Hello! Thanks for your article. I still have one question: When you do <component v-bind:is="something"></component> If "something" c...
 

Hi Lain,

You welcome :)

It will depend if the something is an lazy loaded component or component definition object.

In your case I will reckon you fetch the article from the database and then render, in that case if the response of the api is empty or 404 you can render a fallback component.

 

Thank you for your quick response!

I was hoping for something like <div v-except-nonexists> or something like that.

In my case, I have no way to trigger any 404 error, because each article's component is registered using it's metadata (name, tags, ...), and then it's loaded lazily only when my <component> tag asks for it. But Vue does nothing at all if the given component does not exists.

I'll keep my whitelist solution because the solution you provides implies to rewrite the whole loading system: I register a (lazy) component from each article, keep track of all registered articles, and if the article referenced by the location hash has never been registered, I show an error with v-if/v-else:

  <component v-if="loaded_articles[curent_page]" :is="curent_page"></component>
  <div v-else class="article article-content">
    <previous-button></previous-button>
    <h3>{{curent_page}}</h3>
    <p>{{$t("articles.article_not_found")}}</p>
  </div>

This method prevents any additional request to the server...

It if you loading through webpack, it's simple, because import will throw an exception.

What do you mean by:

Vue does nothing at all if the given component does not exists.

You should be able to add that condition to v-if, no?

Are you registering the components using Vue.component()?

No, I don't use webpack.

Yes, I use Vue.component(name, promise) to register my components.

When my Vue instance is mounted, I set the language, and it triggers the loading of corresponding articles' components. Here is a simplified version of my code:

    function load_article(article, header, err_code) {
        // here, "article" is the raw html of my article
        // We'll insert it into the article's template
        return {
            data: {// some data...
            },
            template: `a template ${article} that encapsulate each article`
        }
    }
    function loader (header) {
        return (resolve, reject) => {
            vm.make_promise({
                url: `/article/${lang}/${header.name}.html`
            })
            .then((data) => {
                resolve(load_article(data, header, 200))
            })
            .catch((data) => {
                resolve(load_article(data, header))
            });
        }
    }
    var lang = vm.lang;
    headers = articles_headers();
    var loaded_articles = {};
    for(var i in headers) {
        header = headers[i];
        Vue.component(`${lang}-${header.name}`, loader(header));
        loaded_articles[`${lang}-${header.name}`] = true;
    }
    return loaded_articles;

And then, I have the code I wrote in my previous comment, with "curent_page" being the name of the article.

But, if we provide an article name that does not exists (and so, a component that is not registered), Vue shows a warning in the console, and that's all: [Vue warn]: Unknown custom element ....

Perhaps there's a way to tell Vue to call a given function when this happens?

you should be able to check if the component is register by accessing Vue.options.components

Code of Conduct Report abuse