2

I am pretty new to VueJs, so I am still figuring things out. Since our templates are stored in the database, I want my templates to load async. For my components I now use the component-factory approach.

var c = Vue.component('my-async-component', function(resolve, reject){ 
  setTimeout(function(){
    resolve({
      template: '<div class="loader">loaded asynchronous: {{ pageName }}</div>',
      data() {
        return {
          pageName: 'my Page'
        }
      }
    })
  },2000)
})

But is it possible to have some kind of placeholder while loading it? I know I can do something with But in that case I need to have a parent component and I would like this to be independent.

On a Vue-instance you can do stuff in the render function end hook it up to mounted like:

var app = new Vue({
  el: '#app',
  data: {
    finish: false,
    template: null
  },
  render: function(createElement) {
    if (!this.template) {
      return createElement('div', 'loading...');
    } else {
      return this.template();
    }
  },
  mounted() {
    var self = this;
    $.post('myUrl', {foo:'bar'}, function(response){
      var tpl = response.data.template;
      self.template = Vue.compile(tpl).render;
    })
  }
})

Is this possible in a component? And is this still working when I have some nested divs (see an other question of mine: here)

1 Answer 1

2

Ok, I figured it out. I just needed to reed de VUE guide a little bit bettter. I just followed the advanced async example from the docs and now I have a working example.

So I have my template like this:

    <div id="app">
      <my-async-component></my-async-component>
    </div>

Then in my JS I declared the template like:

    var c = Vue.component('my-async-component', function(){
      return {
        component: new Promise(function(resolve, reject){
          // setTimeout to simulate an asynchronous call
          setTimeout(function(){ 
            resolve({
              template: '<div class="loader">loaded asynchronous</div>'
            })
          },3000)
        }),
        loading: Vue.component('loader', {
          template: '<p>loading...</p>'
        }),
        error: Vue.component('load-error', {
          template: '<p>error loading component</p>'
        }),
        delay: 200,
        timeout: 10000
      }
    })

    var vm = new Vue({
      el: '#app'
    });

The loading and error components could also be globally registered components, so it's easy to reuse.

Hopefully I could help someone with this answer to my own question.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.