1. Beispiel: Hiermit können Daten und Methoden direkt abgerufen werdenBeispiel: const vm = neuer Vue({ Daten: { Name: "Ich bin Ruochuan", }, Methoden: { sagName(){ konsole.log(dieser.name); } }, }); console.log(vm.name); // Ich bin Ruochuanconsole.log(vm.sayName()); // Ich bin Ruochuan Auf diese Weise kann ich ausgeben, dass ich Ruochuan bin. Neugierige werden sich fragen, warum hierauf direkt zugegriffen werden kann. Warum also kann Funktion Person(Optionen){ } const p = neue Person({ Daten: { Name: „Kleinanzeigen“ }, Methoden: { sagName(){ konsole.log(dieser.name); } } }); Konsole.log(p.name); // undefiniert console.log(p.sayName()); // Nicht abgefangener TypeError: p.sayName ist keine Funktion Wenn Sie es wären, wie würden Sie es erreichen? Lassen Sie uns anhand dieser Fragen den Vue2-Quellcode debuggen und lernen. 2. Bereiten Sie die Umgebung vor und debuggen Sie den Quellcode, um mehr herauszufinden Sie können lokal einen neuen Ordner <script src="https://unpkg.com/[email protected]/dist/vue.js"></script> <Skript> const vm = neuer Vue({ Daten: { Name: "Ich bin Ruochuan", }, Methoden: { sagName(){ konsole.log(dieser.name); } }, }); Konsole.log(VM-Name); Konsole.log(vm.sayName()); </Skript> Installieren Sie dann npm i -g http-server CD-Beispiele http-Server. // Falls der Port belegt ist, können Sie den Port auch http-server -p 8081 angeben. Auf diese Weise können Sie die gerade geschriebene Seite
Drücken Sie nach dem Aktualisieren der Seite F11, um die Funktion aufzurufen. Der Haltepunkt gelangt in den Vue-Konstruktor. 2.1 Vue-KonstruktorFunktion Vue (Optionen) { wenn (!(diese Instanz von Vue) ) { warnen('Vue ist ein Konstruktor und sollte mit dem Schlüsselwort ‚new‘ aufgerufen werden'); } this._init(Optionen); } // Initialisieren initMixin(Vue); Zustandsmixin(Vue); EreignisseMixin(Vue); LebenszyklusMixin(Vue); : renderMixin(Vue); Erwähnenswert ist Folgendes jQuery = Funktion (Selektor, Kontext) { //Gibt das neue Objekt zurück return new jQuery.fn.init( selector, context ); }; Weil
2.2 _init Initialisierungsfunktion Nach dem Aufrufen der Funktion // Code wurde gelöscht Funktion initMixin (Vue) { Vue.prototype._init = Funktion (Optionen) { var vm = dies; // eine UID vm._uid = uid$3++; // ein Flag, um zu verhindern, dass dies beobachtet wird vm._isVue = true; // Merge-Optionen if (Optionen && Optionen._istKomponente) { // Instanziierung interner Komponenten optimieren // da das Zusammenführen dynamischer Optionen ziemlich langsam ist und keine der // Interne Komponentenoptionen erfordern eine besondere Behandlung. initInternalComponent(vm, Optionen); } anders { vm.$optionen = mergeOptionen( Konstruktoroptionen auflösen(vm.constructor), Optionen || {}, vm ); } // wahres Ich enthüllen vm._self = vm; initLifecycle(vm); : InitEvents(vm); initRender(vm); callHook(vm, 'vorErstellen'); initInjections(vm); // Injektionen vor Daten/Eigenschaften auflösen // Initialisierungsstatus initState(vm); initProvide(vm); // provide nach data/props auflösen callHook(vm, 'erstellt'); }; }
2.3 initState Initialisierungsstatus Gemessen am Funktionsnamen sind die Hauptfunktionen dieser Funktion:
Funktion initState (vm) { vm._watchers = []; var opts = vm.$optionen; wenn (opts.props) { initProps(vm, opts.props); } // Es wurden Methoden übergeben, Initialisierungsmethode if (opts.methods) { initMethods(vm, opts.methods); } //Daten eingeben, Daten initialisieren wenn (opts.data) { initData(vm); } anders { beobachten(vm._data = {}, true /* asRootData */); } wenn (opts.computed) { initComputed(vm, opts.computed); } wenn (opts.watch && opts.watch !== nativeWatch) { initWatch(vm, opts.watch); } } Wir konzentrieren uns auf
2.4 Initialisierungsmethode initMethodsFunktion initMethods (vm, Methoden) { var props = vm.$options.props; für (var Schlüssel in Methoden) { { if (Typ der Methoden[Schlüssel] !== 'Funktion') { warnen( "Methode \"" + Schlüssel + "\" hat den Typ \"" + (Typ der Methoden[Schlüssel]) + "\" in der Komponentendefinition. " + "Haben Sie die Funktion richtig referenziert?", vm ); } wenn (Requisiten und hasOwn (Requisiten, Schlüssel)) { warnen( ("Methode \"" + Taste + "\" wurde bereits als Eigenschaft definiert."), vm ); } if ((Schlüssel in vm) && isReserved(Schlüssel)) { warnen( "Methode \"" + Schlüssel + "\" steht im Konflikt mit einer vorhandenen Vue-Instanzmethode. " + „Vermeiden Sie die Definition von Komponentenmethoden, die mit _ oder $ beginnen.“ ); } } vm[Schlüssel] = Typ der Methoden[Schlüssel] !== 'Funktion' ? noop : binden(Methoden[Schlüssel], vm); } } Die Funktion
Abgesehen von diesen Beurteilungen können wir sehen, dass die Funktion Deshalb können wir hierüber direkt auf die Funktionen in Wir können die Maus auf die 2.4.1 bind gibt eine Funktion zurück und ändert, worauf diese zeigtFunktion polyfillBind (fn, ctx) { Funktion boundFn (a) { var l = Argumente.Länge; Rückkehr l ? l > 1 ? fn.apply(ctx, Argumente) : fn.call(ctx, a) : fn.aufruf(ctx) } boundFn._length = fn.länge; Rückgabewert boundFn } Funktion nativeBind (fn, ctx) { gibt fn.bind(ctx) zurück } var bind = Funktion.prototype.bind ? nativeBind :polyfillBind; Einfach ausgedrückt ist es mit der alten Version kompatibel, die die native
2.5 initData Daten initialisieren
Funktion initData (vm) { var Daten = vm.$Optionen.Daten; Daten = vm._Daten = Datentyp === 'Funktion' ? getData(Daten, vm) : Daten || {}; wenn (!isPlainObject(data)) { Daten = {}; warnen( 'Datenfunktionen sollten ein Objekt zurückgeben:\n' + „https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function“, vm ); } // Proxy-Daten auf der Instanz var keys = Objekt.keys(Daten); var props = vm.$options.props; var Methoden = vm.$options.methods; var i = Schlüssel.Länge; während (i--) { var Schlüssel = Schlüssel[i]; { if (Methoden && hasOwn(Methoden, Schlüssel)) { warnen( ("Methode \"" + Schlüssel + "\" wurde bereits als Dateneigenschaft definiert."), vm ); } } wenn (Requisiten und hasOwn (Requisiten, Schlüssel)) { warnen( "Die Dateneigenschaft \"" + Schlüssel + "\" ist bereits als Prop deklariert. " + "Stattdessen den Standardwert der Eigenschaft verwenden.", vm ); } sonst wenn (!isReserved(Schlüssel)) { Proxy (vm, "_data", Schlüssel); } } // Daten beobachten beobachten(Daten, wahr /* asRootData */); } 2.5.1 Daten abrufen Wenn es sich um eine Funktion handelt, rufen Sie die Funktion auf und führen Sie sie aus, um das Objekt zu erhalten. Funktion getData (Daten, vm) { // #7573 Deaktivierung der Dep-Sammlung beim Aufrufen von Datengettern Ziel drücken(); versuchen { gibt Daten zurück.Aufruf(vm, vm) } fangen (e) { Fehlerbehandlung(e, vm, "data()"); zurückkehren {} Endlich popZiel(); } } 2.5.2 Proxy Tatsächlich wird /** * Führen Sie keine Operation aus. * Stubbing von Argumenten, um Flow zufriedenzustellen, ohne nutzlosen transpilierten Code zu hinterlassen * mit ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/). */ Funktion noop (a, b, c) {} var sharedPropertyDefinition = { aufzählbar: wahr, konfigurierbar: true, bekomme: noop, gesetzt: noop }; Funktion Proxy (Ziel, Quellschlüssel, Schlüssel) { sharedPropertyDefinition.get = Funktion ProxyGetter () { gib dies zurück[sourceKey][key] }; sharedPropertyDefinition.set = Funktion ProxySetter (Wert) { dies[Quellschlüssel][Schlüssel] = Wert; }; Object.defineProperty(Ziel, Schlüssel, gemeinsam genutztePropertyDefinition); } 2.5.3 Object.defineProperty definiert Objekteigenschaften
2.6 Einige im Artikel vorkommende Funktionen werden nun endlich einheitlich erklärt2.6.1 hasOwn Handelt es sich um eine Eigenschaft, die dem Objekt selbst gehört?Drücken Sie im Debugmodus die Alt-Taste und bewegen Sie die Maus über den Methodennamen, um zu sehen, wo die Funktion definiert ist. Klicken Sie, um zu springen. /** * Prüfen, ob ein Objekt die Eigenschaft besitzt. */ var hasOwnProperty = Object.prototype.hasOwnProperty; Funktion hasOwn (Objekt, Schlüssel) { returniere hasOwnProperty.call(Objekt, Schlüssel) } hasOwn({ a: undefiniert }, 'a') // wahr hasOwn({}, 'a') // falsch hasOwn({}, 'hasOwnProperty') // falsch hasOwn({}, 'toString') // falsch // Es ist eine Eigenschaft der Eigenschaft selbst und wird nicht nach oben durch die Prototypenkette gesucht. 2.6.2 isReserved Ob es sich um eine interne private reservierte Zeichenfolge handelt, die mit $ und _ beginnt/** * Prüfen Sie, ob eine Zeichenfolge mit $ oder _ beginnt */ Funktion ist reserviert (str) { var c = (str + '').charCodeAt(0); Rückgabe c === 0x24 || c === 0x5F } istReserviert('_data'); // wahr istReserviert('$optionen'); // wahr isReserved('data'); // falsch isReserved('Optionen'); // falsch 3. Abschließend wird eine vereinfachte Version mit über 60 Zeilen Code implementiertFunktion noop (a, b, c) {} var sharedPropertyDefinition = { aufzählbar: wahr, konfigurierbar: true, bekomme: noop, gesetzt: noop }; Funktion Proxy (Ziel, Quellschlüssel, Schlüssel) { sharedPropertyDefinition.get = Funktion ProxyGetter () { gib dies zurück[sourceKey][key] }; sharedPropertyDefinition.set = Funktion ProxySetter (Wert) { dies[Quellschlüssel][Schlüssel] = Wert; }; Object.defineProperty(Ziel, Schlüssel, gemeinsam genutztePropertyDefinition); } Funktion initData(vm){ const data = vm._data = vm.$options.data; const keys = Objekt.keys(Daten); var i = Schlüssel.Länge; während (i--) { var Schlüssel = Schlüssel[i]; Proxy (vm, „_data“, Schlüssel); } } Funktion initMethods(vm, Methoden){ für (var Schlüssel in Methoden) { vm[Schlüssel] = Typ der Methoden[Schlüssel] !== 'Funktion' ? noop : Methoden[Schlüssel].bind(vm); } } Funktion Person(Optionen){ lass vm = dies; vm.$options = Optionen; var opts = vm.$optionen; wenn(opts.data){ initData(vm); } wenn(opts.methods){ initMethods(vm, opts.methods) } } const p = neue Person({ Daten: { Name: „Kleinanzeigen“ }, Methoden: { sagName(){ konsole.log(dieser.name); } } }); Konsole.log(p.name); // Vor der Implementierung: undefiniert // 'Kleinanzeigen' console.log(p.sayName()); // Vor der Implementierung: Nicht abgefangener TypeError: p.sayName ist keine Funktion // 'Kleinanzeigen' 4. Fazit Die in diesem Artikel behandelten Grundkenntnisse sind im Wesentlichen folgende:
Dieser Artikel soll Fragen beantworten, die von Lesern des Quellcodes gestellt werden. Er beschreibt ausführlich, wie man den Vue-Quellcode debuggt, um die Antwort zu finden. Dies ist das Ende dieses Artikels über den Quellcode, der erklärt, warum Vue2 Daten und Das könnte Sie auch interessieren:
|
<<: Detaillierte Erklärung der reinen SQL-Anweisungsmethode basierend auf JPQL
>>: MySQL-Gruppe durch Gruppieren mehrerer Felder
Vorwort Kürzlich stieß ich auf eine Anforderung, ...
Vorbereitung 1. Starten Sie die virtuelle Maschin...
Einfache Verwendung des Vue-Busses Beschreibung d...
In diesem Artikelbeispiel wird der spezifische Co...
1. COUNT(*) und COUNT(COL) COUNT(*) führt normale...
Zeichnen Sie einige der Prozesse der Verwendung d...
Es gibt erhebliche Unterschiede zwischen CentOS7 ...
Lassen Sie mich kurz das Funktionsszenario erklär...
Übersicht über partitionierte MySQL-Tabellen Da M...
1. Zählen Sie die Anzahl der Benutzer, deren Stan...
Cursor Ein Cursor ist eine Methode zum Anzeigen o...
Grundlegende SQL-Anweisungen MySQL-Abfrageanweisu...
Problembeschreibung (die folgende Diskussion besc...
Inhaltsverzeichnis Einführung in das Decorator-Mu...
Nachdem der Server, auf dem sich Docker befindet,...