Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS2 v-html with filter

Tags:

How to display raw html with filter?

I have something like this:

K.json = function( json ) {     if( typeof json!='string' ) json = JSON.stringify( json, null, 2 );     json = json.replace( /</g, '&lt;' ).replace( />/g, '&gt;' ); // replace(/&/g, '&amp;')     var pattern = /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g;     var html = json.replace( pattern, function( match ) {         var cls = 'number';         var suffix = '';         if( /^"/.test( match ) ) {             if( /:$/.test( match ) ) {                 cls = 'key';                 match = match.slice( 0, -1 );                 suffix = ':'             } else {                 cls = 'string';             }         } else if( /true|false/.test( match ) ) {             cls = 'boolean';         } else if( /null/.test( match ) ) {             cls = 'null';         }         return '<span class="' + cls + '">' + match + '</span>' + suffix;     } );     return html; }; Vue.filter( 'json', K.json ); 

And use them something like this:

<div v-html="thecolumn | json"></div> 

It shows a warning and displayed incorrectly:

vue.js:523 [Vue warn]: Property or method "json" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.  

(found in root instance)

I also tried solution from forum: https://laracasts.com/discuss/channels/vue/use-a-filter-custom-filter-in-v-html-property?page=1

<p v-html="this.$options.filters.json(description)"></p> 

It shows error:

[Vue warn]: Error when rendering root instance:  vue.js:3063 Uncaught TypeError: Cannot read property 'filters' of undefined     at eval (eval at makeFunction (vue.js:8260), <anonymous>:2:2975)     at Proxy.renderList (vue.js:3158)     at Proxy.eval (eval at makeFunction (vue.js:8260), <anonymous>:2:2169)     at Vue$3.Vue._render (vue.js:3054)     at Vue$3.<anonymous> (vue.js:2430)     at Watcher.get (vue.js:1661)     at new Watcher (vue.js:1653)     at Vue$3.Vue._mount (vue.js:2429)     at Vue$3.$mount (vue.js:6000)     at Vue$3.$mount (vue.js:8327) 

What's the correct way to do this on VueJS2?

like image 721
Kokizzu Avatar asked Jan 17 '17 04:01

Kokizzu


2 Answers

For completeness, you have some options, like:

  • v-html="$options.filters.FILTERNAME(args)" or
  • :inner-html.prop="args | FILTERNAME" or
  • v-html="METHODNAME(args)", if you create a method.

See demo below.

function json(text) {    // do your magic    return text.toUpperCase(); // just for demo  }    Vue.filter('json', function (value) {      return json(value);  })    new Vue({    el: '#app',    data: {      message: 'Hello Vue.js!'    },    methods: {      jsonMethod(v) {        return json(v); // create a "proxy" to the outer function      }    }  })
<script src="https://unpkg.com/vue"></script>    <div id="app">    <p v-html="$options.filters.json(message)"></p>        <p :inner-html.prop="message | json"></p>        <p v-html="jsonMethod(message)"></p>  </div>
like image 80
acdcjunior Avatar answered Sep 29 '22 03:09

acdcjunior


For me, as @acdcjunior pointed out, this worked:

<p v-html="$options.filters.json(description)"></p> 

Besides that, I had two filters to apply, and it also worked:

<p v-html="$options.filters.filter1($options.filters.filter2(description))"></p> 
like image 30
Xavi Baz Avatar answered Sep 29 '22 03:09

Xavi Baz