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