Vue js text highlight filter

前端 未结 4 542
甜味超标
甜味超标 2020-12-31 08:55

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.

相关标签:
4条回答
  • 2020-12-31 09:28

    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>')
    });
    
    0 讨论(0)
  • 2020-12-31 09:32

    You need to use {{{ foo | highlight }}} with 3 braces, not with 2 {{}}. Two braces escapes HTML.

    0 讨论(0)
  • 2020-12-31 09:34

    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

    0 讨论(0)
  • 2020-12-31 09:45

    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/

    0 讨论(0)
提交回复
热议问题