Dans Vue JS, appelez un filtre à partir d'une méthode à l'intérieur de l'instance vue

86

Disons que j'ai une instance Vue comme ceci:

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?
        }
    }
}

Je peux facilement utiliser le filtre dans un modèle comme celui-ci:

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

Mais comment puis-je utiliser ce filtre à partir d'une méthode d'instance ou d'une propriété calculée? (Évidemment, cet exemple est trivial et mes filtres actuels sont plus complexes).

harryg
la source

Réponses:

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

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

Moz Morris
la source
13
Toi beauté!!
Mere Development
1
Cela ne fonctionne pas pour moi dans un contexte Nuxt. this.$optionsn'a pas de filterspropriété.
Jay Bienvenu
5
Dans NuxtJS utiliserthis.$root.$options.filters
Emanuel S.
28

C'est ce qui a fonctionné pour moi

  1. Définition du filtre

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

    import Vue from 'vue'
    let text = Vue.filter('truncate')(sometextToTruncate, 18);
    
Olexiy Zamkoviy
la source
La faille dans cette réponse est de s'appuyer sur import Vue from 'vue'et de créer une nouvelle variable alors qu'elle existe déjà.
Jay Bienvenu
3

Vous pouvez créer une vuexfonction d'assistance similaire pour mapper des filtres enregistrés globalement dans l'objet de méthodes d'un composant vue:

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

Usage:

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

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

si votre filtre est quelque chose comme ça

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

c'est la réponse

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

Pour compléter la réponse de Morris, voici un exemple de fichier que j'utilise normalement pour mettre des filtres à l'intérieur, que vous pouvez utiliser dans n'importe quelle vue en utilisant cette méthode.

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
la source
Ce n'est jamais une bonne idée de déclarer les choses dans une portée globale, ce qui windows.Vueet windows.momentfait, sauf si vous devez absolument le faire, sans autre moyen.
J.Ko
Pas vrai du tout pour ces sujets! Les filtres définis globalement par projet sont une bonne règle!
realtebo