Search code examples
vue.jsvuejs2vue-filter

Vue filters migration from vue 1 to vue 2


I have problem with migratiing filters from vue 1 to vue 2, I created exactly what I need here (highlighting text which match the input text):

Vue.component('demo-grid', {
  template: '#grid-template',
  props: {
    filterKey: String
  },
  data: function () {
    return {
     searchParams: [
     { key: '' }
     ],
      suggestions: [
        { message: 'Foo' },
        { message: 'Bar' },
        { message: 'Foobar' },
        { message: 'pikachu' },
        { message: 'raichu' }
      ]
    }
  },
  filters: {
    highlight: function(words, query){
        var iQuery = new RegExp(query, "ig");
        return words.replace(iQuery, function(matchedTxt,a,b){
            return ('<span class=\'highlight\'>' + matchedTxt + '</span>');
        });
    }
  }
})


// bootstrap the demo
var demo = new Vue({
  el: '#demo'
})

https://jsfiddle.net/t5ac1quc/23/ VUE-1 resource
https://jsfiddle.net/t5ac1quc/25/ VUE-2 resource

I would be very grateful, for all the answers


Solution

  • Updated fiddle.

    <template id="grid-template">
      <ul>
        <li v-for="suggest in suggestions" v-html="highlight(suggest.message, filterKey)"></li>
      </ul>
    </template>
    
    <div id="demo">
      <form>
        Search <input v-model="searchParams.key">
      </form>
      <demo-grid :filter-key="searchParams.key"></demo-grid>
    </div>
    
    Vue.component('demo-grid', {
      template: '#grid-template',
      props: {
        filterKey: String
      },
      data: function () {
        return {
          suggestions: [
            { message: 'Foo' },
            { message: 'Bar' },
            { message: 'Foobar' },
            { message: 'pikachu' },
            { message: 'raichu' }
          ]
        }
      },
      methods: {
        highlight: function(words, query) {
          var iQuery = new RegExp(query, "ig");
          return words.replace(iQuery, function(matchedTxt,a,b){
              return ('<span class=\'highlight\'>' + matchedTxt + '</span>');
          });
        }
      }
    })
    
    new Vue({
      el: '#demo',
      data: {
        searchParams: {
          key: '',
        },
      },
    });
    

    Summary:

    • When using <script> tags to store templates, set type="template" (or similar) to prevent the browser from executing the template as JavaScript. Or better yet use <template> instead.
    • {{{ html }}} syntax is no longer supported. In Vue 2 you must use the v-html directive instead.
    • Since v-html is a directive (and doesn't use {{ }} interpolation), it doesn't use the filter syntax. Use a method instead.
    • You had some issues with the scope of the data. The root component needs to define data for searchParams which is used in its template. Also searchParams was an array but you weren't using it as an array (searchParams.key); this will not work with Vue 2 (all reactive data properties must be properly declared upfront).