source

VueJS2 v-html(필터 포함)

goodcode 2022. 8. 29. 22:08
반응형

VueJS2 v-html(필터 포함)

필터와 함께 raw 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$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)

VueJS2에서 이 작업을 수행하는 올바른 방법은 무엇입니까?

완성도를 높이기 위해 다음과 같은 옵션이 있습니다.

  • 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>

이 문제는 필터가 Vue 인스턴스에 추가되기 전에 HTML이 처리된다는 것입니다.이렇게 해보세요: 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>

언급URL : https://stackoverflow.com/questions/41688899/vuejs2-v-html-with-filter

반응형