Rufen Sie in Vue JS einen Filter aus einer Methode in der Vue-Instanz auf

86

Angenommen, ich habe eine Vue-Instanz wie folgt:

new Vue({
    el: '#app',

    data: {
        word: 'foo',
    },

    filters: {
       capitalize: function(text) {
           return text.replace(/(?:^|\s)\S/g, function(a) { return a.toUpperCase(); });
       }
    },

    methods: {
        sendData: function() {
            var payload = this.$filters.capitalize(this.word); // how?
        }
    }
}

Ich kann den Filter einfach in einer Vorlage wie folgt verwenden:

<span>The word is {{ word | capitalize }}</span>

Aber wie kann ich diesen Filter innerhalb einer Instanzmethode oder einer berechneten Eigenschaft verwenden? (Offensichtlich ist dieses Beispiel trivial und meine tatsächlichen Filter sind komplexer).

Harryg
quelle

Antworten:

203
this.$options.filters.capitalize(this.word);

Siehe http://vuejs.org/api/#vm-options

Moz Morris
quelle
13
Du schöne!!
Bloße Entwicklung
1
Dies funktioniert bei mir in einem Nuxt-Kontext nicht. this.$optionshat keine filtersEigenschaft.
Jay Bienvenu
5
In NuxtJS verwendenthis.$root.$options.filters
Emanuel S.
28

Das hat bei mir funktioniert

  1. Filter definieren

    //credit to @Bill Criswell for this filter
    Vue.filter('truncate', function (text, stop, clamp) {
        return text.slice(0, stop) + (stop < text.length ? clamp || '...' : '')
    });
    
  2. Filter verwenden

    import Vue from 'vue'
    let text = Vue.filter('truncate')(sometextToTruncate, 18);
    
Olexiy Zamkoviy
quelle
Der Fehler in dieser Antwort besteht darin import Vue from 'vue', eine neue Variable zu erstellen, wenn bereits eine vorhanden ist.
Jay Bienvenu
3

Sie können eine vuexähnliche Hilfsfunktion erstellen , um global registrierte Filter dem Methodenobjekt einer vue-Komponente zuzuordnen:

// map-filters.js
export function mapFilters(filters) {
    return filters.reduce((result, filter) => {
        result[filter] = function(...args) {
            return this.$options.filters[filter](...args);
        };
        return result;
    }, {});
}

Verwendung:

import { mapFilters } from './map-filters';

export default {
    methods: {
        ...mapFilters(['linebreak'])
    }
}
Ahmad Mobaraki
quelle
1

wenn Ihr Filter so etwas ist

<span>{{ count }} {{ 'item' | plural(count, 'items') }}</span>  

das ist die Antwort

this.$options.filters.plural('item', count, 'items')
Uygar
quelle
0

Um die Antwort von Morris zu ergänzen, ist dies ein Beispiel für eine Datei, die ich normalerweise zum Einfügen von Filtern verwende. Sie können sie mit dieser Methode in jeder Ansicht verwenden.

var Vue = window.Vue
var moment = window.moment

Vue.filter('fecha', value => {
  return moment.utc(value).local().format('DD MMM YY h:mm A')
})

Vue.filter('ago', value => {
  return moment.utc(value).local().fromNow()
})

Vue.filter('number', value => {
  const val = (value / 1).toFixed(2).replace('.', ',')
  return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.')
})
Vue.filter('size', value => {
  const val = (value / 1).toFixed(0).replace('.', ',')
  return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.')
})
Kiko Seijo
quelle
Es ist niemals eine gute Idee, Dinge in einem globalen Bereich zu deklarieren, was windows.Vueund windows.momenttut es, wenn Sie es nicht unbedingt müssen, ohne einen anderen Weg.
J.Ko
Für diese Themen überhaupt nicht wahr! Global definierte Filter pro Projekt sind eine gute Regel!
Realtebo