Vue: Fügen Sie benutzerdefinierte V-Modell-Modifikatoren hinzu

Erstellt am 13. Sept. 2016  ·  52Kommentare  ·  Quelle: vuejs/vue

Wir haben .lazy , .number , .trim und .undef sind unterwegs.

Abgesehen von .lazy funktionieren sie alle wie Zwei-Wege-Filter.

Da 2.0 keine 2-Wege-Filter unterstützt, sollte es möglicherweise eine neue API geben, um benutzerdefinierte V-Modell-Modifikatoren hinzuzufügen, um denselben Bedarf zu erfüllen.

feature request

Hilfreichster Kommentar

Gibt es eine Chance, dass wir dieses Problem wieder öffnen können? Ein häufiger Anwendungsfall für mich ist die Notwendigkeit, Daten in einem Feld automatisch zu formatieren, während sie eingegeben werden. So etwas wie „101216“ zu nehmen und es in „10/12/16“ umzuwandeln. In der Lage zu sein, einen benutzerdefinierten V-Modell-Modifikator zu erstellen, würde meinen Code erheblich vereinfachen, da ich v-model.date schreiben könnte, anstatt eine benutzerdefinierte Eingabekomponente mit Requisiten und Ereignissen erstellen zu müssen.

Alle 52 Kommentare

Von @posva berechnete Eigenschaften sind nicht wiederverwendbar.

Fast alles ist durch ein Mixin wiederverwendbar.
Sie können eine Funktion verwenden, die ein Mixin generiert. Auf diese Weise können Sie eine binden
berechnete Eigenschaft dynamisch. Ich kann dieses Beispiel jetzt nicht auf eine Geige setzen
aber ich würde es so schnell wie möglich machen.
Ich stimme jedoch zu, dass dies ein sehr häufiger Anwendungsfall für Eingaben ist
Transformationen angewendet. Eine richtige API oder zumindest eine Erklärung dazu
Anleitung ist notwendig

Am Di, 13. September 2016, 18:48 Francisco Lourenço, [email protected]
schrieb:

@posva https://github.com/posva berechnete Eigenschaften sind nicht wiederverwendbar.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/vuejs/vue/issues/3666#issuecomment -246746524, oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAoicf33lCvETQc9LBQ5GGZ93ExPcLS_ks5qptPegaJpZM4J7vQ0
.

Fast alles ist durch ein Mixin wiederverwendbar.
Sie können eine Funktion verwenden, die ein Mixin generiert. Auf diese Weise können Sie eine binden
berechnete Eigenschaft dynamisch. Ich kann dieses Beispiel jetzt nicht auf eine Geige setzen
aber ich würde es so schnell wie möglich machen.
Ich stimme jedoch zu, dass dies ein sehr häufiger Anwendungsfall für Eingaben ist
Transformationen angewendet. Eine richtige API oder zumindest eine Erklärung dazu
Anleitung ist notwendig

Anders ausgedrückt: Berechnete Eigenschaften sind nicht wiederverwendbar. Sie können Factory-Funktionen + Mixins als Workaround verwenden , aber die Benutzerfreundlichkeit und Lesbarkeit sind nicht vergleichbar.

Für mein Projekt habe ich diese Funktion dringend benötigt, also habe ich den empfohlenen benutzerdefinierten Eingabeansatz verwendet:

InputCustom.js

define(function () {
  return Vue.extend({
    data: function () {
      return {
        focused: false
      };
    },
    template: '<input @focus="onFocus" @blur="onBlur" @input="onInput" @change="setDisplayValue">',
    props: ['value'],
    watch: {
      value: function () {
        if (!this.focused) {
          this.setDisplayValue();
        }
      }
    },
    mounted: function () {
      this.setDisplayValue();
    },
    methods: {
      onInput: function () {
        this.$emit('input', this.parse(this.$el.value));
      },
      onFocus: function () {
        this.focused = true;
      },
      onBlur: function () {
        this.focused = false;
        this.setDisplayValue();
      },
      setDisplayValue: function () {
        this.$el.value = this.format(this.value);
      }
    }
  });
});

InputText.js

define(['js/InputCustom'], function (InputCustom) {
  return InputCustom.extend({
    methods: {
      parse: function (val) {
        val = val.trim();
        return val === '' ? null : val;
      },
      format: function (val) {
        return val === null ? '' : val;
      }
    }
  });
});

Meiner Meinung nach ist dieser Ansatz sehr praktisch und ich habe mich entschieden, überhaupt keine v-Modell-Modifikatoren zu verwenden, einschließlich .lazy .

Für individuellere Anwendungsfälle, die integrierte Modifikatoren nicht unterstützen können, ist das, was @ecmel erwähnt, der empfohlene Ansatz. Wir werden dies im offiziellen Leitfaden ausführlicher dokumentieren.

Die Idee dieses Funktionsvorschlags besteht darin, die vorhandene v-model -Direktive zu nutzen, die bereits mit jedem input -Element funktioniert. Um die Arbeit des Schreibens von _InputCustom.js_ in jedem Projekt zu sparen, da dies bereits in v-model getan wurde, muss nur das Äquivalent von _InputText.js_ in einen benutzerdefinierten Modifikator geschrieben werden, der die gesamte erforderliche Logik enthält meistens modifiziert werden. Die Tatsache, dass v-model bereits mit Modifikatoren geliefert wird, beweist, dass es sich um ein intuitives und wünschenswertes Muster handelt. Es ist nur natürlich, die Erstellung benutzerdefinierter Modifikatoren zu erleichtern, um die Arbeit beim Erstellen benutzerdefinierter Elemente und das manuelle Implementieren der Dom/Modell-Bindung zu sparen.

Wenn es aus der API-Perspektive sinnvoll ist, wäre es interessant zu wissen, welche technischen Einschränkungen die Entscheidung zur Nichtimplementierung dieser Funktion vorantreiben.

Gibt es eine Chance, dass wir dieses Problem wieder öffnen können? Ein häufiger Anwendungsfall für mich ist die Notwendigkeit, Daten in einem Feld automatisch zu formatieren, während sie eingegeben werden. So etwas wie „101216“ zu nehmen und es in „10/12/16“ umzuwandeln. In der Lage zu sein, einen benutzerdefinierten V-Modell-Modifikator zu erstellen, würde meinen Code erheblich vereinfachen, da ich v-model.date schreiben könnte, anstatt eine benutzerdefinierte Eingabekomponente mit Requisiten und Ereignissen erstellen zu müssen.

Nachdem ich vue js jetzt eine Weile in meinem Projekt verwendet habe, denke ich, dass dieses Problem tatsächlich erneut geöffnet werden sollte.

Zumindest brauchen wir einen undef Modifikator.

Ich stimme zu, dass dieses Thema erneut aufgegriffen werden sollte. Ich bin mir nicht sicher, was undef tun sollte, aber ich hätte gerne einen v-model -Modifikator, der meine Variable auf null setzt, falls der getrimmte Wert der Eingabe eine leere Zeichenfolge ist.

Ich würde das gerne auf einfache Weise selbst machen können.

Redundantere Funktionen als diese wurden beispielsweise mit https://github.com/vuejs/vue/issues/5194 hinzugefügt. Von außen scheint Vue langsam einige seiner Prinzipien zugunsten von Konventionen und Praktiken zu kompromittieren, die von der Reaktionsgemeinschaft gefördert werden. Leicht abweichend von den Qualitäten, die ihn überhaupt erst auszeichneten. Wäre interessant zu wissen, ob dies eine bewusste Entscheidung mit der Absicht ist, die Abwanderung zu erleichtern, oder nur Zufall.

Das Schreiben benutzerdefinierter Komponenten ist in Ordnung, aber wenn Sie eine benutzerdefinierte Komponente eines Drittanbieters wie https://github.com/text-mask/text-mask/tree/master/vue#readme verwenden möchten, gibt es keine direkte Möglichkeit, die maskierten Komponenten zu bereinigen Eingaben in Modellwerte, mit Ausnahme der Verwendung berechneter Eigenschaften.

Ich möchte also nur ein HTML-Standard-Eingabefeld [type=date] verwenden, um einen Datumstyp in meinem Modell zu bearbeiten, und dieses wunderbar leistungsstarke und erweiterbare Framework kann das nicht sofort tun? Kann das Datum nicht in das Feld einlesen, überschreibe mein Datum mit einer Zeichenfolge in meinen Daten, nachdem ich ein Datum ausgewählt habe. Diese Lösung könnte in zwei Zeilen mit Zweiwegfiltern oder mit Modifikator geschrieben werden.

Aber die beste Lösung wäre es, es einfach nativ zu unterstützen, wie sie es für Checkboxen und andere Standardeingabefelder tun, warum ist "Datum" etwas Besonderes?

+1 für benutzerdefinierte Modifikatoren. Scheint ein Kinderspiel zu sein, es sei denn, es gibt einen guten Grund, es nicht zu tun?

Das Maskieren der Eingabe und das Analysieren des Werts für die Verwendung durch die Anwendung ist eine sehr gängige Praxis, und es wäre erstaunlich, etwas "syntaktischen Zucker" wie v-model.lazy.currency="amount" zu erstellen!

1+ für benutzerdefinierte Modifikatoren.
Ich habe eine einfache Funkeingabe mit true|false-Werten, die zu Zeichenfolgen ausgewertet werden - aber ich brauche sie als booleschen Wert - berechnete Eigenschaften sind in diesem Fall nicht intelligent, da ich eine berechnete Eigenschaft für jede Funkeingabe neu implementieren muss. Beispiel: 100 Funkeingaben führen zu 100 berechneten Eigenschaften

+1 für benutzerdefinierte Modifikatoren, aber ich stimme tobei zu - input[type=date] sollte automatisch funktionieren.

+1 für benutzerdefinierte Modifikatoren.

Ich habe einen Angular-Hintergrund und habe gerade mit vue angefangen und diesen Thread gesehen.

Ich denke, es würde wirklich helfen, so etwas wie die Parser und Formatierer von Angular zu haben, auch in Vue. Wenn ich so etwas wie v-model.dateFormat machen und so etwas wie mm/tt/jjjj erhalten könnte, wäre das wirklich cool.

BEARBEITEN: sieht so aus, als würde es wiederholen, was @restored18 gesagt hat. +1 auch für dich

+1 für benutzerdefinierte V-Modell-Modifikatoren.

In meinem Fall überschleife ich einige verschachtelte Objekte, die in JSON abgerufen werden, und verwende eine einzelne HTML-Vorlage (anstelle einer Vorlage pro Objekt). In diesem Fall glaube ich, dass berechnete Eigenschaften nicht funktionieren?

Ich füge derzeit beim Abrufen und Senden von Daten benutzerdefinierte Konvertierungsmethoden zwischen dem Serverformat und dem V-Modellformat ein, würde aber gerne etwas nur "Eingebautes" haben, an das ich die Funktionen übergeben könnte.

+1 dazu. Früher war es vor 2.2 verfügbar. Sie können auf die Unterkunft zugreifen durch,

this.$vnode.data.directives

Es wurde mit dem Hinzufügen von benutzerdefinierten Modelleingabewerten entfernt, war aber eine sehr nützliche Funktion und sollte wieder im Framework enthalten sein.

+1 dafür.

Benutzerdefinierte V-Modell-Modifikatoren wären großartig!

ich auch

+1 auch 2018 ...

+1 Meiner Meinung nach ist dies eine notwendige Funktion für DRY-Code. Im Moment muss ich 10 Beobachter erstellen, die dasselbe für ein Formular mit viel Eingabe tun. Ein benutzerdefinierter Modifikator würde alles lösen.

+1 Ich habe gerade mit vue begonnen und brauche bereits diese Art von Zwei-Wege-Filtern ...

+1 unbedingt benötigt

+1

Sie können Helfer wie diese für die meisten Anwendungsfälle IMO erstellen

@nickmessing , das den hier beschriebenen (wirklich nützlichen) Anwendungsfall nicht abdeckt, bei dem es sich um eine direkte Änderung des Eingabetexts handelt. Wenn Sie ein Eingabefeld haben, das immer wie ein Telefon formatiert sein soll, hätten Sie <input v-model.phone="some_data"> . Wenn der Benutzer Text eingab, formatierte er ihn automatisch.

Dies scheint eine so grundlegende Funktion zu sein, und es ist schwieriger, als es im Moment sein sollte. Das Verhalten ist bereits im Framework vorhanden, aber aus irgendeinem Grund ist es auf reinen Framework-Code beschränkt. Wir möchten in der Lage sein, einen benutzerdefinierten Modifikator hinzuzufügen, der dies tun würde und der über Komponenten und Projekte hinweg wiederverwendbar ist, genau wie es Filter und Direktiven derzeit sind.

@bbugh stimme voll und ganz zu, ich habe einen ähnlichen Fall mit der Formatierung von IBANs und es wäre so eine nette und deklarative Möglichkeit, einfach v-model.iban="payment.iban" dort einzufügen ...

@franciscolourenco Vielleicht könnte jemand begründen, warum dies nicht vom Framework unterstützt werden sollte, damit es offensichtlicher wird.

+1 für benutzerdefinierte Modifikatoren, es gibt viele Anwendungsfälle, die mit dieser Funktion erreicht werden könnten

In unserer Anwendung gibt es nur wenige verschiedene Eingaben zum Formatieren von Währungen. Wir speichern immer Cent-Beträge im Modell, zeigen aber schön formatierte Dollarbeträge in Eingaben an (also 123456 im Modell als 1.234,56 $ angezeigt) <input v-model.dollars="cents" />

Ein weiterer Anwendungsfall ist das Bereinigen und Aufheben von HTML-Feldern, um XSS-Angriffe zu verhindern (das Modell speichert „ A &amp; B “, während die Eingabe „ A & B “ anzeigt) <input v-model.html="text" />

+1

+1

+1 für benutzerdefinierte Modifikatoren.
Ich war wirklich überrascht, dass ich so etwas wie v-model.trim.uppercase=... nicht machen kann

+1

+1

+1

+1
Native v-model Eingabemodifikatoren wären eine großartige Funktion. Wie die Leute hier erwähnen, gibt es viele Anwendungsfälle. Ich brauchte Datums- und Währungsmodifikatoren für alle Projekte, an denen ich gearbeitet habe.

Sollen wir hier ein Thema eröffnen? https://github.com/vuejs/rfcs

Ich habe dem bereits +1 gegeben, möchte aber eine Notiz für Leute werfen, die „jetzt“ etwas brauchen

Während der Modifikator viel effizienter ist, konnte ich den gleichen Effekt mit einer transparenten Eingabe/Komponente mit einem berechneten Getter/Setter-Feld erzielen.

Ich kann ein Beispiel teilen, wenn jemand es braucht

Wir haben dies nicht implementiert, da bei dieser scheinbar einfachen Funktion viele Dinge zu beachten sind:

  • Die eingebauten Modifikatoren sind tatsächlich Hinweise zur Kompilierzeit, die unterschiedlichen kompilierten Code generieren. Benutzerdefinierte Modifikatoren müssen wahrscheinlich mithilfe einer Laufzeitkonfiguration definiert werden, was ein anderer Mechanismus ist.

  • Welche Art von API sollten wir für die Laufzeitkonfiguration dafür verfügbar machen?

  • Wir hatten in der Vergangenheit Zwei-Wege-Filter. Eine bidirektionale Werttransformation erfordert, dass der Benutzer eine einwandfreie Logik implementiert, damit sich die bidirektionale Bindung stabilisieren kann. Andernfalls riskieren Sie, Ihre gesamte App für Grenzfälle in eine Endlosschleife zu versetzen.

    • Der Grund, warum wir .number und .trim haben, ist, dass es sich tatsächlich um Einwegtransformationen handelt (die nur angewendet werden, wenn der DOM-Wert mit Komponentendaten synchronisiert wird) und sich daher garantiert stabilisieren.
  • Wie sollten sich benutzerdefinierte Modifikatoren verhalten, wenn v-model für eine Komponente verwendet wird?

  • Wie sollten sich benutzerdefinierte Modifikatoren bei Nicht-Text-Eingabetypen verhalten, z. B. radio , checkbox und vor allem <select> ?

All diese Fragen sind unbeantwortet und machen die Anfrage komplexer als es scheint. Aus diesem Grund stimme ich zu, dass es ein guter Kandidat für einen richtigen RFC wäre, der all dies abdeckt, wenn jemand diese Funktion wirklich haben möchte. Bis dahin bringen mehr +1 es in keiner Weise voran.

@rkeon Es gibt bereits ein Beispiel in https://github.com/vuejs/vue/issues/3666#issuecomment -249583603, aber wenn Ihres anders/besser ist, posten Sie es einfach. Es kann für Anfänger nützlich sein.

@Gotterbild Ich habe dieses Beispiel vermisst, aber es ist in späteren Versionen von Vue viel zu kompliziert (das hätte eine vortransparente Komponentenunterstützung sein können).

Hier ist eine sehr einfache, die ich habe, die nur einen Prozentsatz in Dezimalzahlen umwandelt (dh: 4,5 -> 0,045) und umgekehrt ("View" -Wert und "Model" -Wert)

<template>
    <input type="number" v-on="listeners" v-model="innerValue">
</template>

<script>

    export default {
        props: ['value'],
        computed: {
            listeners () {
                const { input, ...listeners } = this.$listeners
                return listeners
            },
            innerValue: {
                get () {
                    return (this.value) ? `${(this.value * 100)}` : ''
                },
                set (_val) {
                    const val = (_val) ? (_val / 100) : ''
                    this.$emit('input', val)
                }
            }
        }
    }

</script>

Dies ist einfacher als oben, da Sie nicht den gesamten Fokus / Unschärfe / etc. neu festlegen müssen

@yyx990803 vielen Dank für weitere Hintergrundinformationen zu diesem Thema.

Für meine Anwendungsfälle "brauche" ich keine benutzerdefinierten Modifikatoren. Es ist nur so, dass es aus Verbrauchersicht sinnvoll wäre, dass vue eine Möglichkeit hat, Ihre eigene zu bauen. Das hat es im Grunde für alles, außer Modifikatoren 😄

Während ich Wege finden könnte, etwas zu erstellen, das meine Transformationslogik richtig kapselt und das ich wiederverwenden könnte, denke ich, dass eine geeignete API für solche Anwendungsfälle eine viel breitere Möglichkeit eröffnen würde, gemeinsamen Code durch eine Sammlung von „Best- Modifikatoren üben".

Ich kam hierher, weil ich nach einem Modifikator suchte, um Zeichenfolgen in Großbuchstaben umzuwandeln
Ich wollte es wie v-model.uppercase="username" erstellen

Am Ende habe ich eine benutzerdefinierte Direktive verwendet

Vue.directive('uppercase', {
    update (el) {
        el.value = el.value.toUpperCase()
    },
})

<input type="text" v-model="username" v-uppercase>

Benutzerdefinierte Anweisungen sollten als Alternative ausreichen.
Oder gibt es etwas, das nur mit dem benutzerdefinierten V-Modell-Modifikator möglich ist?

@Christhofernatalius , wenn man bedenkt, dass v-model einfach eine Anweisung ist, könnten Sie nicht die v-model zugunsten der benutzerdefinierten Anweisung eliminieren? Auf diese Weise aktualisieren Sie nicht zweimal?

@Christhofernatalius , wenn man bedenkt, dass v-model einfach eine Anweisung ist, könnten Sie nicht die v-model zugunsten der benutzerdefinierten Anweisung eliminieren? Auf diese Weise aktualisieren Sie nicht zweimal?

@rkeon Wird es zweimal aktualisiert?
Also, wenn ich kein v-model verwende, muss ich dann auch einen Bind- und Unbind-Hook für den Eingabe-Listener hinzufügen und den Benutzernamenwert aktualisieren?

BEARBEITEN: Wird die Verwendung von berechnet mit Setter und Getter nicht auch zweimal aktualisiert?
BEARBEITEN 2: Ich habe versucht, den Watcher und die Anweisung zu protokollieren, die jeweils nur einmal für jeden Tastendruck gedruckt werden.

Ich habe es nicht ausprobiert, nur Spekulation - ich nehme an, die Idee von zwei Direktiven, um einen Wert zu aktualisieren, fühlt sich für mich ein bisschen komisch an, aber wenn Sie es überprüft haben, sehe ich nichts Falsches daran.

Meine Komponentenumgehung hat auch Einschränkungen, weshalb ich immer noch für einen Modifikator bin - dh: Er erfordert ein Element, mehr Renderzeit und funktioniert nur als Komponente in der Art und Weise, wie diese Komponente definiert ist (dh: ein Eingabefeld ) vs. in der Lage zu sein, es sogar einfach für eine beliebige Komponente / ein beliebiges Element zu verwenden, das die Macht einer Richtlinie hat.

zwei Möglichkeiten, die Katze zu häuten, schön, Optionen zu haben :)

Gibt es dafür einen RFC?

Ich glaube nicht

Ich könnte es erstellen, aber bedeutet es nur, ein Problem in diesem RFC-Repo oder etwas anderem hinzuzufügen?

https://github.com/vuejs/rfcs#what -the-process-is beantwortet das Ihre Frage?

Kann das bitte wieder geöffnet werden? Eine benutzerdefinierte Direktive kann in einigen Fällen funktionieren, aber das Verhalten kann lustig sein, Beispiel:

Vue.directive('number', {
  update: function(el, binding, vnode) {
    el.value = el.value.replace(/[^\d.]/g, '');
  },
});

Wenn Sie diese Direktive (zusammen mit einem v-Modell) hinzufügen und bei jedem zweiten Tastendruck sehr schnell Buchstaben eingeben, wird v-model nicht mehr mit el.value synchronisiert. Und da Sie das empfangene Bindungsobjekt nicht ändern können, gibt es keine Möglichkeit, das v-Modell innerhalb dieser Direktive "neu zu implementieren".

@jeankvd Ich weiß, es fühlt sich übertrieben an, aber eine Wrapper-Komponente wird am zuverlässigsten sein (siehe Beispiel oben).

Mit einer Wrapper-Komponente können Sie auch "mehr tun". In Ihrem "Zahlen"-Beispiel wird das v-Modell im Idealfall tatsächlich zu einem Number . In Ihrem Ansatz ist es immer noch ein String .

Was ist, wenn Sie den leeren Wert anpassen möchten? Leerer String? Null? Nicht definiert? -- Sie können eine Stütze für emptyValue übergeben und als solche festlegen.

Während ich mich einst dafür einsetzte, wurde mir kurz darauf klar, dass Modifikatoren viel zu viele Einschränkungen haben und es weit besser ist, nur eine Komponente zu haben (zumindest imo).

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen