Search code examples
javascriptvue.jsvuejs2javascript-framework

vue.js render ajax data that contains vue.js syntax


Vue.js version is: 2.x

Hi. I'm sending an ajax request in vue js to another page and getting it's source which contains vue.js syntax such as events. When this source is added to property and property added to a template, the ajax data source (that contains vue.js syntax) can not be rendered and does not work properly. For example template is:

<div id="app">
    {{{ foo }}}
</div>

and app.js is:

var app = new Vue({
    el: '#app',
    data: {
        foo: 'bar'
    },
    mounted(){
        this.$http.get('/media').then(function(response){
            data = response.body;
            Vue.set(app, 'foo', data);
        });
    },
    methods: {
        alertVideoLink: function(event){
            alert(event.target.href);
        }
    }
});

In the above app.js code, ajax request returns this code (that is response.body):

<a href="/media/videos" @click.pevent.self="alertVideoLink(event)">Video Link</a>

but this link can't be rendered and does not work properly! I'm testing the render method and some useful hints, but no way found. Please help... Thanks


Solution

  • Sounds like you want to use an Async Component.

    Something like...

    components: {
      'async-media': () => Vue.http.get('/media').then(res => ({
        template: res.body,
        methods: {
          alertVideoLink (event) {
            this.$emit('click', event)
          }
        }
      }))
    }
    

    Then in your template...

    <async-media @click="handleClickEventFromChildComponent" />
    

    Here's an example using a timeout to fake "load" a template

    var app = new Vue({
      el: '#app',
      data: {},
      components: {
        'async-media': () => new Promise(resolve => {
          setTimeout(() => {
            resolve({
              template: '<a href="/media/videos" @click.prevent.self="alertVideoLink($event)">Video Link</a>',
              methods: {
                alertVideoLink(event) {
                  this.$emit('click', event.target.href)
                }
              }          
            })
          }, 2000)
        })
      },
      methods: {
        handleClickEventFromChildComponent (href) {
          console.info('Clicked on', href)
        }
      }
    });
    <div id="app">
      <p>Wait 2 seconds</p>
      <async-media @click="handleClickEventFromChildComponent" />
    </div>
    <script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>