I need help writing a text highlight filter using vuejs. The idea is to loop through a given array of words and if there is a match, apply a span with a class to that word. The problem I have is that, I can't seem to return data with html formatting with vuejs. Any ideas will be highly appreciated. I am really stuck with this.
Vue.filter('highlight', function(words, query){
    //loop through **words** and if there is a match in **query**
   //apply a <span> with some style
   //At the end return formatted string to html page
})
                HTML interpolations {{{ foo }}} have been removed in favor of the v-html directive in vuejs2.X, thus from version 2.x, Vue.js allows for raw JavaScript templating (React-style) in addition to HTML templating.
@jeff's answer is correct but for vuejs 1.x versions, but in case {{{}}} didn't work for you guys or if you want to evaluate the tags in the HTML, and from a trusted source, example, if you want to add a <strong></strong> tag, then you need to use v-html, the v-html to ask Vue to evaluate the string as HTML:
<span v-html="$options.filters.highlight(item, val)">{{ item }}</span>
highlight filter:
Vue.filter('highlight', function(word, query){
  var check = new RegExp(query, "ig");
  return word.toString().replace(check, function(matchedText,a,b){
      return ('<strong>' + matchedText + '</strong>');
  });
});
or you can use @Thomas Ferro's filter
As Jeff just said, the basic mustaches interprets the data as plain text.
You can add your span by replacing the query with the String.replace() method.
Here's a basic example: https://jsfiddle.net/0jew7LLz/
Vue.filter('highlight', function(words, query) {
    return words.replace(query, '<span class="highlight">' + query + '</span>')
});
                        The idea is to use split and keep the words that the regex matches.
Here is a user safe component that escapes html and highlights a regexp that searches for multiple words:
Vue.component('child', {
  props: ['msg', 'search', 'effect'],
  template: '<span><span v-for="(s, i) in parsedMsg" v-bind:class="getClass(i%2)">{{s}}</span></span>',
  methods: {
    getClass: function(i) {
      var myClass = {};
      myClass[this.effect] = !!i;
      return myClass;
    },
  },
  computed: {
    parsedSearch : function () {
        return '(' + this.search.trim().replace(/ +/g, '|') + ')';
    },
    parsedMsg: function() {
        return this.msg.split(
        new RegExp(this.parsedSearch , 'gi'));
    }
  }
})
new Vue({
  el: '#app',
  }
  // ...
})
Usage example:
<div id="app">
  <child msg="My life so good and awesome, is'nt it great?" search="   life   is   good  " effect='highlight'> </child>
</div>
jsfiddle:
https://jsfiddle.net/50xvqatm/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With