Eine kurze Diskussion über die Rolle von Vue3 defineComponent

Eine kurze Diskussion über die Rolle von Vue3 defineComponent

Die Funktion „defineComponent“ kapselt einfach die Setup-Funktion und gibt ein Optionsobjekt zurück.

Exportfunktion defineComponent(Optionen: unbekannt) {
  returniere isFunction(Optionen) ? { setup: Optionen } : Optionen
}

Das Wichtigste an defineComponent ist, dass es der Komponente in TypeScript die richtige Parametertypinferenz verleiht.

Bildbeschreibung hier einfügen

defineComponent-Überladungsfunktion

1: Direkt-Setup-Funktion

// Überladung 1: Direkt-Setup-Funktion
// (verwendet benutzerdefinierte Props-Schnittstelle)
Exportfunktion defineComponent<Props, RawBindings = Objekt>(
  aufstellen: (
    Requisiten: Nur lesbar<Requisiten>,
    ctx: Setup-Kontext
  ) => RawBindings | Renderfunktion
): DefineComponent<Props, RawBindings>

Bildbeschreibung hier einfügen

2: Objektformat ohne Requisiten

// Überladung 2: Objektformat ohne Requisiten
// (verwendet benutzerdefinierte Props-Schnittstelle)
// Rückgabetyp ist für Vetur- und TSX-Unterstützung
Exportfunktion defineComponent<
  Requisiten = {},
  RawBindings = {},
  D = {},
  C erweitert ComputedOptions = {},
  M erweitert MethodOptions = {},
  Mixin erweitert ComponentOptionsMixin = ComponentOptionsMixin,
  Erweitert erweitert ComponentOptionsMixin = ComponentOptionsMixin,
  E erweitert EmitsOptions = EmitsOptions,
  EE erweitert Zeichenfolge = Zeichenfolge
>(
  Optionen: ComponentOptionsWithoutProps<Props,RawBindings,D,C,M,Mixin,Extends,E,EE>
): DefineComponent<Props, RawBindings, D, C, M, Mixin, Extends, E, EE>

Bildbeschreibung hier einfügen

3: Objektformat mit Array-Props-Deklaration

// Überladung 3: Objektformat mit Array-Props-Deklaration
// Requisiten abgeleitet als { [Schlüssel in PropNames]?: beliebig }
// Rückgabetyp ist für Vetur- und TSX-Unterstützung
Exportfunktion defineComponent<
  PropNames erweitert String,
  Rohbindungen,
  D,
  C erweitert ComputedOptions = {},
  M erweitert MethodOptions = {},
  Mixin erweitert ComponentOptionsMixin = ComponentOptionsMixin,
  Erweitert erweitert ComponentOptionsMixin = ComponentOptionsMixin,
  E erweitert EmitsOptions = Record<string, any>,
  EE erweitert Zeichenfolge = Zeichenfolge
>(
  Optionen: ComponentOptionsWithArrayProps<
    Requisitennamen,
    RawBindings,...>
): DefineComponent<
  Schreibgeschützt<{ [key in PropNames]?: any }>,
  RawBindings,...>

Bildbeschreibung hier einfügen

4: Objektformat mit Objekteigenschaftendeklaration

// Überladung 4: Objektformat mit Objekteigenschaftendeklaration
// siehe „ExtractPropTypes“ in ./componentProps.ts
Exportfunktion defineComponent<
  // die Readonly-Einschränkung erlaubt TS, den Typ von { required: true } zu behandeln
  // als Konstante statt als Boolean.
  PropsOptions erweitert Readonly<ComponentPropsOptions>,
  Rohbindungen,
  D,
  C erweitert ComputedOptions = {},
  M erweitert MethodOptions = {},
  Mixin erweitert ComponentOptionsMixin = ComponentOptionsMixin,
  Erweitert erweitert ComponentOptionsMixin = ComponentOptionsMixin,
  E erweitert EmitsOptions = Record<string, any>,
  EE erweitert Zeichenfolge = Zeichenfolge
>(
  Optionen: ComponentOptionsWithObjectProps<
    PropsOptions, RawBindings, D, C, M, Mixin, Erweitert, E, EE>
): DefineComponent<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>

Bildbeschreibung hier einfügen

Entwicklungspraxis

Abgesehen von der grundlegenden Verwendung in Unit-Tests gibt es bei der folgenden ParentDialog-Komponente einige Punkte zu beachten:

So schreiben Sie benutzerdefinierte Komponenten und globale Komponenten

Typbeschränkungen für Inject, Ref usw.

So schreiben Sie das Setup und das entsprechende H-Injektionsproblem

So schreiben Sie V-Modell und ScopedSlots in TSX

ParentDialog.vue

<script lang="tsx">
importiere { noop, trim } von „lodash“;
importieren {
  injizieren, Ref, Komponente definieren, aktuelleInstanz abrufen, ref
} von '@vue/composition-api';
Filter aus „@/filters“ importieren;
importiere CommonDialog aus „@/components/CommonDialog“;
importiere ChildTable, { getEmptyModelRow } aus './ChildTable.vue';
 
Schnittstelle IParentDialog exportieren {
  anzeigen: Boolesch;
  specFn: (component_id: HostComponent['id']) => Promise<{ data: DictSpecs }>;
}
 
exportiere StandarddefineComponent<IParentDialog>({
  // Benutzerdefinierte Komponenten in tsx müssen noch Komponenten registrieren: {
    Kindertabelle
  },
  Requisiten: {
    zeigen: {
      Typ: Boolean,
      Standard: false
    },
    Spezifikationsfunktion: {
      Typ: Funktion,
      Standard: noop
    }
  },
 
  // Hinweis: Beim Setup muss die Pfeilfunktion setup: (props, context) => { verwendet werden.
 
    // Beheben Sie das Problem, dass die Funktion „h“ nicht automatisch in tsx eingefügt werden kann // eslint-disable-next-line no-unused-vars
    const h = getCurrentInstance()!.$createElement;
 
    const { emit } = Kontext;
    const { specFn, anzeigen } = Requisiten;
 
    // Verwendung des Filters const { withColon } = filters;
 
    // Inject-Verwendung const pageType = inject<CompSpecType>('pageType', 'foo');
    const dictComponents = inject<Ref<DictComp[]>>('dictComponents', ref([]));
    
    // Ref-Typbeschränkung const dictSpecs = ref<DictSpecs>([]);
    const laden = ref(false);
 
    const _lookupSpecs = async (component_id: HostComponent['id']) => {
      wird geladen.Wert = wahr;
      versuchen {
        const json = warte auf specFn(Komponenten-ID);
        dictSpecs.Wert = json.data;
      Endlich
        wird geladen.Wert = falsch;
      }
    };
 
    const formdata = ref<Spezifikation>({
      Komponenten-ID: '',
      specs_id: '',
      Modell: [getEmptyModelRow()]
    });
    const err1 = ref('');
    const err2 = ref('');
    
    const _doCheck = () => {
      err1.Wert = '';
      err2.Wert = '';
      
      const { Komponenten-ID, Spezifikations-ID, Modell } = Formulardaten.Wert;
      wenn (!Komponenten-ID) {
        err1.value = „Bitte wählen Sie eine Komponente aus“;
        gibt false zurück;
      }
      für (lass i = 0; i < Modell.Länge; i++) {
        const { Marken-ID, Daten } = Modell[i];
        wenn (!brand_id) {
          err2.value = „Bitte wählen Sie eine Marke aus“;
          gibt false zurück;
        }
        Wenn (
          formdata.value.model.some(
            (m, midx) => midx !== i && String(m.Marken-ID) === String(Marken-ID)
          )
        ) {
          err2.value = 'Markenduplikat';
          gibt false zurück;
        }
      }
      gibt true zurück;
    };
 
    const onClose = () => {
      emittieren('update:show', false);
    };
    const onSubmit = async () => {
      const bool = _doCheck();
      wenn (!bool) zurückgeben;
      const params = formdata.value;
      emittieren('senden', Parameter);
      beimSchließen();
    };
 
    // Hinweis: In TSX müssen global registrierte Komponenten wie Element-UI weiterhin das Kebab-Case-Format verwenden????‍
    return () => (
      <CommonDialog
        Klasse="Komp"
        Titel="Neu"
        Breite="1000px"
        labelCancel="Abbrechen"
        labelSubmit="OK"
        vLaden={Ladewert}
        anzeigen={anzeigen}
        beimSchließen={beimSchließen}
        beim Senden = {beim Senden}
      >
        <el-form labelWidth="140px" class="Seite erstellen">
         <el-form-item label={withColon('Komponententyp')} erforderlich={true} Fehler={err1.value}>
            <el-Auswahl
              Klasse="volle Breite"
              Modell={{
                Wert: formdata.value.component_id,
                Rückruf: (v: Zeichenfolge) => {
                  formdata.value.component_id = v;
                  _lookupSpecs(v);
                }
              }}
            >
              {dictComponents.value.map((dictComp: DictComp) => (
                <el-option key={dictComp.id} label={dictComp.component_name} value={dictComp.id} />
              ))}
            </el-Auswahl>
          </el-form-item>
          {formdata.value.komponenten_id ? (
              <el-form-item labelWidth="0" label="" erforderlich={true} Fehler={err2.value}>
                <untergeordnete Tabelle
                  Liste={formdata.value.model}
                  beiÄnderung={(v: Spec['model']) => {
                    formdata.value.model = v;
                  }}
                  beiFehler={(err: string) => {
                    err3.Wert = Fehler;
                  }}
                  scopedSlots={{
                      Standard: (Umfang: beliebig) => (
                        <p>{ Umfang.foo }</p>
                      )
                  }}
                />
              </el-form-item>
          ) : null}
        </el-form>
      </CommonDialog>
    );
  }
});
</Skript>
 
<style lang="scss" scoped>
</Stil>

Zusammenfassung

  • defineComponent() wurde eingeführt, um Parametertypen von setup()-Komponenten korrekt abzuleiten
  • defineComponent kann sich korrekt an Formen wie keine Props, Array-Props usw. anpassen.
  • defineComponent kann eine explizite benutzerdefinierte Props-Schnittstelle akzeptieren oder automatisch aus einem Eigenschaftsvalidierungsobjekt abgeleitet werden
  • In TSX müssen global registrierte Komponenten wie Element-UI weiterhin das Kebab-Case-Format verwenden.
  • In tsx sollte v-model model={ verwenden. {Wert, Rückruf}} Syntax
  • In tsx sollten Slots mit Gültigkeitsbereich scopedSlots={ verwenden. { foo: (Bereich) => () }} Syntax
  • defineComponent gilt nicht für funktionale Komponenten, verwenden Sie stattdessen RenderContext

Dies ist das Ende dieses Artikels über die Rolle von Vue3 defineComponent. Weitere Informationen zur Rolle von Vue3 defineComponent finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Überlegen Sie, ob Vue3 standardmäßig alle OnSomething-Ereignisse als V-On-Ereignisse bindet.
  • Dieser Artikel zeigt Ihnen, wie Sie Vue 3.0 responsive verwenden
  • Implementierung der schnellen Projektkonstruktion von vue3.0+vant3.0
  • Verwenden Sie Vue3, um eine Komponente zu implementieren, die mit js aufgerufen werden kann
  • Detaillierte Erläuterung des zugrunde liegenden Prinzips von defineCustomElement, hinzugefügt in vue3.2
  • Vue3 Vue-Ereignisbehandlungshandbuch

<<:  Verwenden einer MySQL-Datenbank im Docker, um LAN-Zugriff zu erhalten

>>:  Grafisches Tutorial zur Installation und Konfiguration von MySQL 8.0.18

Artikel empfehlen

HTML-Grundlagen - CSS-Stylesheets, Style-Attribute, Format- und Layoutdetails

1. Position : fest Gesperrte Position (relativ zu...

Welchen MySQL-Eindeutigen Index oder Normalen Index soll ich wählen?

Stellen Sie sich ein Szenario vor, in dem beim En...

Navicat für MySql Visueller Import von CSV-Dateien

In diesem Artikel wird der spezifische Code von N...

Detaillierte Analyse des langsamen Abfrageproblems beim Senden von MySQL-Daten

Anhand eines Beispiels habe ich Ihnen die Lösung ...

Ein kurzer Vortrag über Rx-responsive Programmierung

Inhaltsverzeichnis 1. Beobachtbar 2. Funktionen h...

Detaillierte Erläuterung der MySQL Master-Slave-Datenbankkonstruktionsmethode

Dieser Artikel beschreibt, wie man eine MySQL Mas...

Detaillierte Erläuterung der elastischen CSS3-Erweiterungsbox

verwenden Flexible Boxen spielen beim Front-End-L...

Hinweise zum MySQL-Datenbank-Sicherungsprozess

Heute habe ich mir einige Dinge im Zusammenhang m...

Tipps zur Konvertierung von MySQL-Spalten in Zeilen (teilen)

Vorwort: Weil viele Geschäftstabellen Entwurfsmus...

Eine Codezeile löst verschiedene IE-Kompatibilitätsprobleme (IE6-IE10)

x-ua-compatible wird verwendet, um das Modell für...

Zusammenfassung der Bootstrap-Lernerfahrung - Austausch von Designs im CSS-Stil

Aufgrund der Anforderungen des Projekts habe ich ...