Search code examples
javascripthtmlvue.jsescaping

Vue js unescape only certain HTML tags


I'm using v-html to unescape Html tags But I only want to unescape <a></a> tag in a string. For an example

Input:

<p> Hello World </p> <a target="_blank" href="https://www.google.com/">https://www.google.com/</a> <div></div>

Output: Link is active but all the other tags should be plain text

<p> Hello World </p> https://www.google.com/ <div></div>

How can I unescape only the link tags and leave the other tags plain in Vue?


Solution

  • This is one of those times where it's probably just easiest to use a regex to replace all the < and > with &lt; and &gt; except those around <a> tags

    new Vue({
      el: "#app",
      data: () => ({
        input: `<p> Hello World </p> <a target="_blank" href="https://www.google.com/">https://www.google.com/</a> <div></div>`
      }),
      computed: {
        output: ({ input }) => input
          .replace(/<(?!\/?a( |>))/g, "&lt;")
          .replace(/(?<=&lt;[^>]+)>/g, "&gt;")
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
    <div id="app">
      <div v-html="output"></div>
      <pre>output = {{ output }}</pre>
    </div>

    The two replacements are

    1. Replace any < that is not part of <a> or </a> with &lt;
    2. Replace any > that is now preceded by &lt; with &gt;

    Note that lookbehind assertions don't currently work in any version of Safari.