2016-12-13 10 views
8

Dla prostego przykładu: pole tekstowe do wprowadzania danych walutowych. Wymagane jest wyświetlanie danych użytkownika w formacie "$ 2334,567" i usuwanie kropki dziesiętnej.Jaki jest prawidłowy sposób implementacji formatowania na v-modelu w Vue.js 2.0

Próbowałem dyrektywy vue. Metoda aktualizacji dyrektywy nie jest wywoływana, gdy interfejs użytkownika jest odświeżany z powodu innych elementów sterujących. więc wartość w polu tekstowym powraca do tego bez formatowania.

Próbowałem również v-on: zmień obsługę zdarzeń. Ale nie wiem, jak wywołać funkcję globalną w module obsługi zdarzeń. Nie jest dobrą praktyką tworzenie metody przeliczania walut w każdym obiekcie Vue.

Jaki jest obecnie standardowy sposób formatowania w Vue 2.0?

Pozdrowienia

Odpowiedz

14

Proszę sprawdzić tę pracę jsFiddle przykład: https://jsfiddle.net/mani04/bgzhw68m/

W tym przykładzie, formatowane wejście walutą jest składnikiem w sobie, że używa v-model jak każdy inny element formularza w Vue.js. można zainicjować tego składnika w następujący sposób:

<my-currency-input v-model="price"></my-currency-input> 

my-currency-input jest składnikiem samowystarczalny, który formatuje wartość waluty, gdy pole wejściowe jest nieaktywna. Gdy użytkownik umieści kursor w środku, formatowanie zostanie usunięte, aby użytkownik mógł wygodnie modyfikować wartość.

Oto jak to działa:

Komponent my-currency-input ma wartość obliczoną - displayValue, który ma get i set metody zdefiniowane. W metodzie get, jeśli pole wejściowe nie jest aktywne, zwraca sformatowaną wartość waluty.

Gdy użytkownik wpisze w polu wejściowym, obliczona właściwość set z wartościwyśle ​​wartość za pomocą $emit, powiadamiając komponent macierzysty o tej zmianie.

Odniesienia do używania v-model na niestandardowych składników: https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events

+0

Znacznie lepiej! Cała idea maskowania naprawdę przeszkadza mi, ale to działa dobrze. –

+1

@BillCriswell Dzięki! Nawet ja lubiłem to lepiej niż mój drugi przykład, ponieważ jest to w pełni samodzielny komponent, a szablon nadrzędny jest czysty. – Mani

+2

Podobało mi się twoje podejście, więc trochę go rozszerzyłem: https://jsfiddle.net/crswll/xxuda425/5/ –

4

Oto przykład roboczych: https://jsfiddle.net/mani04/w6oo9b6j/

Działa modyfikując ciąg wejściowy (swoją wartość waluty) podczas ustawiania ostrości-out i skupić się w wydarzeniach, w następujący sposób:

<input type="text" v-model="formattedCurrencyValue" @blur="focusOut" @focus="focusIn"/> 
  1. Kiedy można umieścić kursor w polu wejściowym, trwa this.currencyValue i konwertuje go do zwykłego formatu, dzięki czemu użytkownik może je modyfikować.

  2. Po wpisaniu przez użytkownika wartości i kliknięć w innym miejscu (fokus) wartość this.currencyValue jest ponownie obliczana po zignorowaniu nieliczbowych znaków, a tekst wyświetlany jest sformatowany zgodnie z wymaganiami.

Formater waluty (reg exp) jest copy-paste stąd: How can I format numbers as money in JavaScript?

Jeśli nie chcesz dziesiętny jak wspomniano w pytaniu, można zrobić this.currencyValue.toFixed(0) w metodzie focusOut.

+0

To jedyne rozsądne, a nie denerwujące podejście, jakie widziałem przy wprowadzaniu masek. –

+0

Dzięki, chcę mieć rozwiązanie, które jest bliższe architekturze Vue. Próbowałem użyć właściwości obliczeniowej (brzydkie rozwiązanie, muszę dodać obliczoną właściwość dla każdego wejścia waluty). Teraz, gdy użytkownik wpisze "1111" (łańcuch), wartość modelu wynosi 1111 (liczba). Następnie użytkownik wprowadza ".22" po "1111", seter usuwa kropkę dziesiętną. Ale pole tekstowe wejściowe to 1111.22, ponieważ wartość modelu nadal wynosi 1111, a getter nie zostanie wywołany. – flyfrog

+0

Dodałem kolejną odpowiedź na to pytanie. Ponieważ chodziło o całkowite przepisanie przykładu jsFiddle, postanowiłem dodać oddzielną odpowiedź zamiast edytować tę. Sprawdź, czy spełnia twoje wymagania. Używam obliczonej właściwości, tak jak to określiłeś. Miejsca dziesiętne są obsługiwane wewnętrznie, a wyświetlacz pokazuje tylko precyzję określoną w 'toFixed()' podczas formatowania waluty. – Mani

0

I wdrożone komponent. Zgodnie z odpowiedzią Mani, powinien użyć $ emit.

Vue.component('currency', { 
template: '<input type="text"' + 
      ' class="form-control"' + 
      ' :placeholder="placeholder""' + 
      ' :title="title"' + 
      ' v-model="formatted" />', 
props: ['placeholder', 'title', 'value'], 
computed: { 
    formatted: { 
     get: function() { 
      var value = this.value; 
      var formatted = currencyFilter(value, "", 0); 
      return formatted; 
     }, 
     set: function (newValue) { 
      var cleanValue = newValue.replace(",", ""); 
      var intValue = parseInt(cleanValue, 10); 
      this.value = 0; 
      this.value = intValue; 
     } 
    } 
} 
} 

);

Powiązane problemy