1

I have this js code:

var tags = [
    'b',
    'i'
    'u',
];

var text = 'some simple text';

tags.forEach(tag => {
    text = '<' + tag + '>' + text + '</' + tag + '>';
});

//print wrapped "text" variable on the page (Upd:) like: <b><i><u>Some text</u></i></b>

How to convert this to vue component/template?

3 Answers 3

3

You have two options:

  1. Use Your function to generate html code and then simply put result in v-html <div v-html="xxx" /> Docs: https://v2.vuejs.org/v2/guide/syntax.html#Raw-HTML
  2. Use dynamic components like this https://jsfiddle.net/Herteby/ffe5rban/ Docs: https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components

In Your case first option is better choice. Dynamics components are actually designed for Vue components, not raw html tags - but it's possible to use them this way if You really need to.

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

2 Comments

How it could be done with dynamic components? It should be some kind of recursive component. v-html is the simplest way but doesn't look like the best practice.
Well, it actually is ;)
1

The acceptability of v-html depends on the source of markup data. It shouldn't be used with unsanitized, user-defined HTML, doing this is dangerous and may result in script injections.

This is the case for render function, it allows to build a hierarchy of tags that will be rendered into DOM elements:

export default {
  render(h) {
    return tags.reduceRight(
      (wrapper, tag) => h(tag, [wrapper]),
      text
    );
  }
};

1 Comment

My plans was changed and I didn't finish my task with converting js code to vue but If I will need it again in the future I would choose render function over v-html to achieve the goal. So, I can mark this answer as accepted. Thank you!
1

Create a computed property called tagged and render it inside the template using v-html directive :

var app=new Vue({
  el: "#app",

  data() {
    return {
      text: "some text"
    };
  },
  computed: {
    tagged() {
      var tags = [
        'b',
        'i',
        'u',
      ];
      tags.forEach(tag => {
        this.text = '<' + tag + '>' + this.text + '</' + tag + '>';
      });

      return this.text;

    }
  }

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-html="tagged"></div>
</div>

Second solution is to create a component with the 3 tags and pass the text as prop :

Vue.component('bui-tag', {
  props: ['text'],
  template: `<b><u><i>{{text}}</i></u></b>`
})


var app = new Vue({
  el: "#app",

  data() {
    return {
      text: "some text"
    };
  },
  computed: {
    tagged() {
      var tags = [
        'b',
        'i',
        'u',
      ];
      tags.forEach(tag => {
        this.text = '<' + tag + '>' + this.text + '</' + tag + '>';
      });

      return this.text;

    }
  }

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <bui-tag :text="text" />
</div>

4 Comments

Is v-html the best option?
according to your use case and what you have provided it's a good solution, but if you explain more your use case i think there's other solutions
Second solution isn't a good idea because tags array can contains different values, for example, ['b', 'u'] or ['b', 'i'].
if these tags don't contain any logic like data binding or events, the v-html is the best solution

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.