Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic router-link

I developed some kind of blog with VueJS and VueRouter. So I have a markdown editor in the administration in order to add blog posts.

My problem is: How to make router-links work with dynamic content?

For the time being, I can only add classic <a href="...">foo</a> with the editor. And when the content gets rendered, it's a classic link so when a visitor clicks on the link, the entire website gets reloaded to display the content of the targeted link.

I think that the behaviour I'm looking for is to transform the internal links into router-link and the external links into classic links.

What is your strategy to achieve that in your projects, did someone had ever been confronted to that problem?

Thank you for your advices or ideas.

I explained my problem in a small JSFiddle if you want to see what I talk about: http://jsfiddle.net/El_Matella/museptre/1/

const Home = { 
  template: '<div>Home <div v-html="dynamicContent"></div></div>',
  data () {
    return {
        dynamicContent: '<router-link to="/foo">This is a dynamic link</router-link> and <a href="https://google.com" target="_blank">and this is a classic link</a>'
    }
  }
}

will only render the classic link

like image 879
Hammerbot Avatar asked Nov 28 '17 11:11

Hammerbot


2 Answers

Ok, now I can see what you want to achieve.

Obviously, rendering <router-link></router-link> to static HTML won't work.

You need to generate <rotuer-link> in the template directly. You may use render method to get more flexibility/dynamism or as Vue docs says:

leverage the full programmatic power of JavaScript.

Then you bound to param and content of the link to some dynamic var eg. from data prop.

Example 1. with "simple dynamism" string template:

const Home = { 
  template: '<div>Home <router-link :to="dynamicTo">{{dynamicContent}}</router-link></div>',
  data () {
    return {
        dynamicContent: 'This is a dynamic link',
        dynamicTo: '/foo'
    }
  }
}

Example 2. with "more complex dynamism" and render method:

 render: function(createElement) {
    createElement(
      'router-link', {
        props: {
          to: this.dynamicTo
        }
      }, this.dynamicContent)
}

I didn't check the second example has valid syntax, but you've got an idea how you can use JavaScript to generate a fully customizable template (you can use loops, variables, etc).

It is possible to create a custom component solving the problem and using the render function:

export default {
    props: {
    content: {
        type: String,
      required: true
    }
  },
  render (h) {
    return h(Vue.compile(this.content))
  }
}

and using it this way:

<dynamic-vue-component :content="dynamic"></dynamic-vue-component>

Here is a JSFiddle demonstrating the problem solved: JSFiddle

like image 155
klimat Avatar answered Oct 20 '22 20:10

klimat


Maybe kind of a hack, but I managed to work around this by adding an onclick attribute forcing the router to pick the link and preventing the page from reloading :

 <a href="/the-link/" target="_self" onclick="event.preventDefault(); 
 app._router.push('/the-link/');">Some text.</a>
like image 22
salazarpardo Avatar answered Oct 20 '22 20:10

salazarpardo