Heim Web-Frontend js-Tutorial So übergeben Sie Ereignisse in Vue-Komponenten

So übergeben Sie Ereignisse in Vue-Komponenten

Jun 14, 2018 pm 03:44 PM
vue 事件传递

Meine jüngste Arbeit erfordert die Verwendung von Vue, daher bin ich zuletzt mit Vue in Kontakt gekommen. Jetzt stelle ich Ihnen die Ereignisübertragung zwischen Vue-Komponenten vor

Da die neue Arbeit die Verwendung von Vue erfordert, bin ich in letzter Zeit mit Vue in Kontakt gekommen. Da ich React bereits verwendet habe, habe ich sehr schnell mit Vue angefangen.

Ich habe auch versucht, einige Ähnlichkeiten und Unterschiede zwischen den beiden zu finden. Neben einigen weiteren Hilfsmethoden sollte der größte Unterschied darin bestehen, dass es für die Kommunikation zwischen Komponenten nicht nur Requisiten, sondern auch ein Ereignis gibt Listener, der zwischen Komponenten übergeben werden kann.

In vue2.+ führte Vue jedoch den Diff-Algorithmus und den virtuellen Dom ein, um die Effizienz zu verbessern. Um mit häufigen Aktualisierungen von Dom-Elementen umzugehen, wird eine Optimierungslösung vorgeschlagen. Gibt es einen Konflikt zwischen häufigen Änderungen und Aktualisierungen und der Initialisierung von Ereignis-Listenern? ? Schreiben wir einen einfachen Code, um dies zu überprüfen.

Wir schreiben zwei von p erstellte Schaltflächen, eine ist in HTML-Code geschrieben und die andere wird in Form einer Komponente eingefügt. Die beiden Schaltflächen sind genau gleich, aber wir fügen der äußeren Schaltfläche ein deaktiviertes Attribut hinzu Layer und übergeben if-else, um deaktivierte Schaltflächen zu bestimmen und unterschiedliche Schaltflächen anzuzeigen (natürlich würden wir in normalen Szenarien keinen solchen Code schreiben, hier simulieren wir nur ein spezielles Szenario auf diese Weise und prüfen, ob dieses Szenario in unserem Unternehmen existiert) .

<template>
 <p class="test">
 <p class="btn" v-if="disabled" @click="handleClick">可点击</p>
 <p class="btn" v-else >不可点击</p>
 <Button v-if="disabled" @clickTest="handleClick">可点击</Button>
 <Button v-else>不可点击</Button>
 </p>
</template>

<script>
import Button from &#39;./Button&#39;
export default {
 data () {
 return {
  disabled: true
 }
 },
 methods: {
 handleClick() {
  alert(&#39;可点击&#39;)
 }
 },
 components: {
 Button,
 },
 mounted() {
 setTimeout(() => {
  this.disabled = false
 }, 1000)
 }
}
</script>
<style>
.btn{
 margin: 100px auto;
 width: 200px;
 line-height: 50px;
 border: 1px solid #42b983;
 border-radius: 5px;
 color: #42b983;
}
</style>
Nach dem Login kopieren

Fügen wir einen kleinen Stil hinzu, damit es so gut wie möglich aussieht. Es sieht sehr einfach aus. Zwei Schaltflächen sind an ein Klickereignis gebunden, wenn sie anklickbar sind. Der Unterschied besteht darin, dass es sich bei dem einen um direkt geschriebenen HTML-Code und bei dem anderen um eine Komponente handelt. Der Code der Komponente lautet wie folgt:

<template>
 <p class="btn" @click="handleClick"><slot></slot></p>
</template>
<script>
 export default {
  methods: {
   handleClick() {
    this.$emit(&#39;clickTest&#39;)
   }
  }
 }
</script>
Nach dem Login kopieren

Fügen Sie dann einen 1-sekündigen settimeout zum gemounteten Zeitraum hinzu, um „disabled“ in „false“ zu ändern, und dann testen wir ihn

Wenn „Deaktiviert“ immer noch wahr ist, wird beim Klicken auf beide Schaltflächen eine anklickbare Warnung angezeigt. Wenn sich „disabled“ jedoch in „false“ ändert, wird die in HTML geschriebene nicht mehr angezeigt, die in den folgenden Komponenten geschriebene jedoch weiterhin.

Es ist sehr schwierig, ein solches Problem zu lokalisieren, wenn es auftritt, da der Code dieses Clicktest-Ereignis offensichtlich nicht aufruft und wir auf der Seite auch feststellen können Die Schaltfläche ist nicht mehr anklickbar. Warum wird diese Veranstaltung immer noch ausgerufen?

Beginnen wir mit dem Diff-Algorithmus. Die Algorithmuskomplexität des herkömmlichen Diff-Baum-Algorithmus beträgt O(n^3). Als React den Diff-Algorithmus einführte, wurde die stufenübergreifende Bewegung eliminiert Die Ähnlichkeiten und Unterschiede von Knoten auf derselben Ebene reduzieren die Komplexität des Algorithmus auf O(n), sodass wir die gesamte Seite häufig und ohne Einschränkungen aktualisieren können (natürlich in Maßen).

(haha, kein Bild)

Diff hat eine Strategie, bei der zwei Komponenten mit derselben Klasse eine ähnliche Baumstruktur erzeugen und zwei Komponenten mit unterschiedlichen Klassen unterschiedliche Baumstrukturen erzeugen. Die Vergleichsreihenfolge ist also

1) Baumdiff

2) Komponentendiff

3) Elementdiff

Zurück zu unserem Code, wenn wir Komponente ausführen diff, wir denken, dass es sich um dieselben Komponenten handelt, und führen dann einen Element-Diff aus, d Im DOM in der Komponente hat Vue den Ereignis-Listener, der der Komponente hinzugefügt wurde, nicht gelöscht.

Werfen wir einen Blick auf den Vue-Code

Vue.prototype.$emit = function (event: string): Component {
 const vm: Component = this
 if (process.env.NODE_ENV !== &#39;production&#39;) {
  const lowerCaseEvent = event.toLowerCase()
  if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
  tip(
   `Event "${lowerCaseEvent}" is emitted in component ` +
   `${formatComponentName(vm)} but the handler is registered for "${event}". ` +
   `Note that HTML attributes are case-insensitive and you cannot use ` +
   `v-on to listen to camelCase events when using in-DOM templates. ` +
   `You should probably use "${hyphenate(event)}" instead of "${event}".`
  )
  }
 }
 let cbs = vm._events[event]
 if (cbs) {
  cbs = cbs.length > 1 ? toArray(cbs) : cbs
  const args = toArray(arguments, 1)
  for (let i = 0, l = cbs.length; i < l; i++) {
  try {
   cbs[i].apply(vm, args)
  } catch (e) {
   handleError(e, vm, `event handler for "${event}"`)
  }
  }
 }
 return vm
 }
Nach dem Login kopieren

Vue ermittelt über das _events-Attribut in vdom, ob gebundene Ereignisse vorhanden sind. Wir schauen uns die _events

:
clickTest
:
Array(1)
0
:
ƒ invoker()
length
:
Nach dem Login kopieren

der nicht anklickbaren Schaltfläche an und stellen fest, dass der Clicktest immer noch vorhanden ist. Das ist das Problem.

Wie können wir also ein solches Problem vermeiden? Sollen wir das Problem durch Diff-Vergleich lösen oder uns den Code ansehen?

function sameVnode (a, b) {
 return (
 a.key === b.key && (
  (
  a.tag === b.tag &&
  a.isComment === b.isComment &&
  isDef(a.data) === isDef(b.data) &&
  sameInputType(a, b)
  ) || (
  isTrue(a.isAsyncPlaceholder) &&
  a.asyncFactory === b.asyncFactory &&
  isUndef(b.asyncFactory.error)
  )
 )
 )
}
Nach dem Login kopieren

Das heißt, für Diff ist das sogenannte Same-First-Determination-Prinzip der Schlüssel.

key ist auch ein Attribut, das bei der Einführung von diff hinzugefügt wird. Es wird verwendet, um zu bestimmen, ob die vorderen und hinteren VDOM-Bäume einheitliche Elemente sind (beachten Sie, dass es sich um eine Geschwisterbeziehung handelt), sodass wir nur den Schlüssel hinzufügen müssen Der Code zur Vermeidung dieses Problems

<Button key="1" v-if="disabled" @clickTest="handleClick">可点击</Button>
<Button key="2" v-else>不可点击</Button>
Nach dem Login kopieren

Auf diese Weise wird das Popup-Fenster nicht mehr angezeigt, wenn wir auf die Schaltfläche klicken.

key hat eine breite Palette von Funktionen, wenn wir das Array durchlaufen, um Dom zu generieren. Das Hinzufügen einer bestimmbaren eindeutigen ID (beachten Sie, dass der Array-Index nicht verwendet werden sollte) optimiert unsere Vergleichseffizienz und erfordert weniger Dom-Operationen. Wir werden einem p auch einen Schlüssel hinzufügen, um sicherzustellen, dass es aufgrund von Änderungen in Geschwisterelementen nicht erneut gerendert wird (dieser Typ von p ist normalerweise an andere Ereignisse oder Aktionen als React oder Vue gebunden, z. B. das Generieren einer Leinwand usw.). ).

Gibt es außer dem Hinzufügen dieses unnötigen Schlüsselwerts zur Komponente noch eine andere Möglichkeit, das Problem zu lösen?

Ja, es gibt eine sehr Vue-feindliche, aber reaktionsähnliche Möglichkeit, das Rückrufereignis durch Requisiten weiterzuleiten, wie diese,

<Button v-if="disabled" :clickTest="handleClick">可点击</Button>
<Button v-else>不可点击</Button>
  props: {
   &#39;clickTest&#39;: {
    type: Function
   }
  },
  methods: {
   handleClick() {
    //this.$emit(&#39;clickTest&#39;)
    this.clickTest && this.clickTest()
   }
  }
Nach dem Login kopieren

虽然vue给了我们更方便的事件传递的方式,但props里是允许我们去传递任何类型的,我的期望是在真实的dom上或者在公共组件的入口处以外的地方,都是通过props的方式来传递结果的。虽然这种方式很不vue,而且也享受不到v-on给我们带来的遍历,但是这样确实可以减少不必要的麻烦。

当然既然用了vue,更好的利用vue给我们带来的便利也很重要,所以对于这种很少会出现的麻烦,我们有一个预期,并可以快速定位并修复问题,就可以了。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在vue中如何通过v-for处理数组

使用vue如何实现收藏夹

在node.js中有关npm和webpack配置方法

如何通过js将当前时间格式化?

使用vue引入css,less相关问题

Das obige ist der detaillierte Inhalt vonSo übergeben Sie Ereignisse in Vue-Komponenten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat -Befehle und wie man sie benutzt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So fügen Sie Funktionen zu Schaltflächen für Vue hinzu So fügen Sie Funktionen zu Schaltflächen für Vue hinzu Apr 08, 2025 am 08:51 AM

Sie können der VUE -Taste eine Funktion hinzufügen, indem Sie die Taste in der HTML -Vorlage an eine Methode binden. Definieren Sie die Methode und schreiben Sie die Funktionslogik in der VUE -Instanz.

So verwenden Sie Bootstrap in Vue So verwenden Sie Bootstrap in Vue Apr 07, 2025 pm 11:33 PM

Die Verwendung von Bootstrap in Vue.js ist in fünf Schritte unterteilt: Startstrap installieren. Bootstrap in main.js. Verwenden Sie die Bootstrap -Komponente direkt in der Vorlage. Optional: benutzerdefinierter Stil. Optional: Verwenden Sie Plug-Ins.

So verweisen Sie auf die JS -Datei mit Vue.js So verweisen Sie auf die JS -Datei mit Vue.js Apr 07, 2025 pm 11:27 PM

Es gibt drei Möglichkeiten, sich auf JS -Dateien in Vue.js zu beziehen: Geben Sie den Pfad direkt mit dem & lt; Skript & gt an. Etikett;; Dynamischer Import mit dem montierten () Lebenszyklushaken; und importieren über die Vuex State Management Library.

So verwenden Sie Watch in Vue So verwenden Sie Watch in Vue Apr 07, 2025 pm 11:36 PM

Mit der Watch -Option in Vue.js können Entwickler auf Änderungen in bestimmten Daten anhören. Wenn sich die Daten ändert, löst sich eine Rückruffunktion aus, um Aktualisierungsansichten oder andere Aufgaben auszuführen. Zu den Konfigurationsoptionen gehören unmittelbar, die festlegen, ob ein Rückruf sofort ausgeführt werden soll, und Deep, das feststellt, ob Änderungen an Objekten oder Arrays rekursiv anhören sollen.

So kehren Sie von Vue zur vorherigen Seite zurück So kehren Sie von Vue zur vorherigen Seite zurück Apr 07, 2025 pm 11:30 PM

VUE.JS hat vier Methoden, um zur vorherigen Seite zurückzukehren: $ router.go (-1) $ router.back () verwendet & lt; Router-Link to = & quot;/& quot; Komponentenfenster.history.back () und die Methodenauswahl hängt von der Szene ab.

Vue realisiert Festzelt-/Text -Scrolling -Effekt Vue realisiert Festzelt-/Text -Scrolling -Effekt Apr 07, 2025 pm 10:51 PM

Implementieren Sie Marquee/Text-Scrolling-Effekte in VUE unter Verwendung von CSS-Animationen oder Bibliotheken von Drittanbietern. In diesem Artikel wird die Verwendung von CSS -Animation vorgestellt: Bildlauftext erstellen und Text mit & lt; div & gt;. Definieren Sie CSS -Animationen und setzen Sie Überlauf: Versteckt, Breite und Animation. Definieren Sie Keyframes, setzen Sie Transformation: Translatex () am Anfang und am Ende der Animation. Passen Sie die Animationseigenschaften wie Dauer, Bildlaufgeschwindigkeit und Richtung an.

So verwenden Sie Funktionsabfangweserven So verwenden Sie Funktionsabfangweserven Apr 08, 2025 am 06:51 AM

Funktionsabfangen in VUE ist eine Technik, mit der die Häufigkeit, mit der eine Funktion eingerufen wird, innerhalb eines bestimmten Zeitraums aufgerufen wird und Leistungsprobleme verhindern. Die Implementierungsmethode lautet: Importieren Sie die Lodash -Bibliothek: importieren {dunounce} aus 'lodash'; Verwenden Sie die Dabounce -Funktion, um eine Intercept -Funktion zu erstellen: const dabouncedFunction = dunounce (() = & gt; { / logical /}, 500); Rufen Sie die Abfangfunktion auf und die Steuerfunktion wird höchstens einmal in 500 Millisekunden aufgerufen.

Was bedeutet VUE Multi-Page-Entwicklung? Was bedeutet VUE Multi-Page-Entwicklung? Apr 07, 2025 pm 11:57 PM

VUE Multi-Page-Entwicklung ist eine Möglichkeit, Anwendungen mithilfe des Vue.js-Frameworks zu erstellen, in dem die Anwendung in separate Seiten unterteilt ist: Code-Wartung: Die Aufteilung der Anwendung in mehrere Seiten kann das Verwalten und Wartungsbereich erleichtern. Modularität: Jede Seite kann als separates Modul für eine einfache Wiederverwendung und den Austausch verwendet werden. Einfaches Routing: Die Navigation zwischen Seiten kann durch einfache Routing -Konfiguration verwaltet werden. SEO -Optimierung: Jede Seite hat eine eigene URL, die SEO hilft.

See all articles