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.
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>')
});
You need to use {{{ foo | highlight }}} with 3 braces, not with 2 {{}}. Two braces escapes HTML.
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
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/