VueJS2 v-html 带过滤器

VueJS2 v-html with filter

如何使用过滤器显示原始 html?

我有这样的东西:

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 );

并像这样使用它们:

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

显示警告并显示错误:

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. 

(在根实例中找到)

我也试过论坛的解决方案: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>

显示错误:

[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.Vue._render (vue.js:3054)
    at Vue.<anonymous> (vue.js:2430)
    at Watcher.get (vue.js:1661)
    at new Watcher (vue.js:1653)
    at Vue.Vue._mount (vue.js:2429)
    at Vue.$mount (vue.js:6000)
    at Vue.$mount (vue.js:8327)

在 VueJS2 上执行此操作的正确方法是什么?

问题是您的 HTML 在过滤器添加到您的 Vue 实例之前被处理。试试这样: JSFiddle

var jsonFormatter = 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;
}

new Vue({
    el: '#app',
    data(){
        return {
         jsonData: {dog: 'woof', nestedObject: {cat: 'meow'}}
        }
    },
    filters: {
     jsonFormatter: jsonFormatter
    }
});
//Vue.filter( 'jsonFormatter', jsonFormatter ); // Doesn't work becuase happens after html is processed
<div id="app" class="container">
     <h1>
        v-html directive
    </h1>
    <div v-html="this.$options.filters.jsonFormatter(jsonData)"></div>
</div>

如果您只是显示数据,请创建一个方法:

json(jsonable) {
   return jsonedValue;
}

然后在 html

<div v-html="json(mydata)"></div>

为了完整起见,您有一些选择,例如:

  • v-html="$options.filters.FILTERNAME(args)"
  • :inner-html.prop="args | FILTERNAME"
  • v-html="METHODNAME(args)",如果你创建一个方法。

请参阅下面的演示。

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>

对我来说,正如@acdcjunior 指出的那样,这很有效:

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

除此之外,我有两个过滤器要应用,而且它也有效:

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