No Vue JS, chame um filtro de um método dentro da instância vue

86

Digamos que eu tenha uma instância Vue assim:

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

Posso usar facilmente o filtro em um modelo como:

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

Mas como posso usar este filtro em um método de instância ou propriedade computada? (Obviamente, este exemplo é trivial e meus filtros reais são mais complexos).

harryg
fonte

Respostas:

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

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

Moz Morris
fonte
13
Você ... BELEZA !!
Mero Desenvolvimento de
1
Isso não está funcionando para mim em um contexto Nuxt. this.$optionsnão tem uma filterspropriedade.
Jay Bienvenu
5
Em NuxtJS usethis.$root.$options.filters
Emanuel S.
28

Isto é o que funcionou para mim

  1. Definindo filtro

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

    import Vue from 'vue'
    let text = Vue.filter('truncate')(sometextToTruncate, 18);
    
Olexiy Zamkoviy
fonte
A falha nesta resposta é confiar import Vue from 'vue'e criar uma nova variável quando uma já existe.
Jay Bienvenu
3

Você pode criar uma vuexfunção auxiliar semelhante para mapear filtros registrados globalmente no objeto de métodos de um componente 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;
    }, {});
}

Uso:

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

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

se o seu filtro é algo assim

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

esta é a resposta

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

Para complementar a resposta de Morris, este é um exemplo de arquivo que normalmente uso para colocar filtros dentro, que você pode usar em qualquer visualização usando este método.

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
fonte
Nunca é uma boa ideia declarar as coisas em um escopo global, o que windows.Vuee o windows.momentfaz, a menos que seja absolutamente necessário, sem nenhuma outra maneira.
J.Ko
Isso não é verdade para esses tópicos! Filtros definidos globalmente por projeto é uma boa regra!
realtebo