Blue_Dragon360 Blue_Dragon360 - 6 months ago 48
JSON Question

Vue v-links in JSON data

I am relatively new to Vue, so forgive me if this is obvious (or obviously impossible).

I have a set of JSON data (fetched from a RESTful API via vue-resource):

{content: "This is content. <a href='/blog'> Link to blog </a>"}


Right now, the link triggers a page reload. If it were a vue-router
v-link
, that would not be an issue. However, this doesn't work (quotes are escaped in the data, of course):

{content: "This is content. <a v-link="{ path: '/blog' }"> Link to blog </a>"}


At this point, the template is already parsed, and Vue won't create a v-link anymore (it will just show up as a v-link in the rendered html).

My final result would ideally mean that I could include links in my CMS, either in HTML or Vue format, and have Vue route them correctly as v-links.

Is there something I can do to make Vue interpret the link in the JSON data?

Answer

I've answered the question on Vue Chat, and writing it here in case any other people facing similar problem

Simplified example on Codepen

HTML

<div id="app">
  <div>
    <a v-link= "{path:'/home'}">Go to home</a>
  </div>
  <router-view></router-view>
</div>
<template id="home">
  <div>
    <div>
      Fetched Content:
    </div>
    <div>
      {{{ fetchedContent }}}
    </div>
  </div>
</template>
<template id="route1">
  <div>
    Route1 view
  </div>
</template>
<template id="route2">
  <div>
    Route2 view, this is different from Route1
  </div>
</template>

javascript

function getContent (callback) {
  var content = 'Click this: <a href="/route1">Go to route1</a> and <a href="/route2">Go to route2</a>'
  setTimeout(function () { callback(content) }, 1000)
}
var Home = Vue.component('home',{
  template:'#home',
  data: function () {
    return {
      fetchedContent: 'Loading...'
    };
  },
  ready: function () {
    var self = this
    var router = this.$router

    getContent( function (result) {
      self.fetchedContent = result;
      Vue.nextTick(function () {
        var hyperLinks = self.$el.getElementsByTagName('a')
        Array.prototype.forEach.call(hyperLinks, function (a) {
          a.onclick = function (e) { 
            e.preventDefault()
            router.go({ path: a.getAttribute("href") })
          }
        })
      })
    })
  }
});
var Route1 = Vue.component('route1', {
  template: '#route1'
});
var Route2 = Vue.component('route2', {
  template: "#route2"
});
var router = new VueRouter({
    hashbang:false,
    history:true
});
router.map({
    '/home':{
      component:Home
    },
    '/route1':{
      component:Route1
    },
    '/route2':{
      component:Route2
    }
});
router.start({
}, '#app');