sunscreem
sunscreem

Reputation: 626

Is it possible to DRY html in vuejs components without creating more components?

Lets say you have:

<template>
   <div>
      <!-- html for buttons -->
      <!-- your form -->
      <!-- html for buttons -->
    </div>
</template>
<!-- rest of your component --> 

Is it possible to DRY up the html for the html for buttons without using a separate component? It seems a lot of work to keep adding components just to save repeating 3-4 lines of html?

Upvotes: 0

Views: 202

Answers (1)

Sergeon
Sergeon

Reputation: 6788

I don't know any Vue api that allows to do that properly, however there is a way.

There is v-html which would serve you for DRY html, but it would get rendered as plain HTML, so you cannot use Vue events from there -which I guess your buttons do-.

For instance:

//template 
<div id="app">
  <div v-html="dryContent"></div>
  <p>{{content}}</p>
  <div v-html="dryContent"></div>
    <div v-html="computedString"></div>
</div>


//script
new Vue({
  el: '#app',
  data: {
    content: 'some sentence',
    dryContent: `<div>
<p>Hello world!</p>
</div>`
  },
  computed: {
    computedString() {
      return `<p>${this.content}</p>`
    }
  }
});

Will render the HTML properly. But you cannot setup vue event listeners in the rendered HTML.

You can still, however, setup native listeners:

    dryContent: `<div>
  <p onclick="console.log('foo')">Hello world!</p>
  </div>`

And it will work.

And, well, there is this really obscure pattern which I totally don't suggest but that actually will fit your needs:

new Vue({
  el: '#app',
  data: {
    content: 'some sentence',
    dryContent: `<div>
  <p onclick="modifyContent()">Hello world!</p>
  </div>`
  },
  computed: {
    computedString() {
      return `<p>${this.content}</p>`
    }
  },
  created() {
    window.modifyContent = function() {
      this.content = 'modified!!';
    }.bind(this);
  }
});

You export the component method to a window property, so you can call it from native code.

Don't know your use case, but I'm pretty sure I would just duplicate the HTML code or setup a new component instead of doing this.

Upvotes: 2

Related Questions