Wie kann ich Slot-Änderungen in Vue überwachen? Im folgenden Artikel erfahren Sie, wie Sie Änderungen in Vue-Slots überwachen. Ich hoffe, dass er Ihnen weiterhilft!
In letzter Zeit muss ich den Status einer Komponente aktualisieren, wenn sich ihr Inhalt (Slots, Unterkomponenten usw.) ändert. Im Kontext handelt es sich um eine Formularkomponente, die den Gültigkeitsstatus ihrer Eingaben verfolgt.
Der folgende Codeausschnitt ist im API-Format Options
geschrieben, kann aber in Vue2 und Vue2 verwendet werden, sofern nicht anders angegeben. [Verwandte Empfehlungen: vuejs Video-TutorialOptions
API格式编写的,但除了指定的地方外可以在Vue2 和 Vue2中使用。【相关推荐:vuejs视频教程】
先从控制表单状态开始,根据状态修改一个类,孩子内容使用<slot/>
填充:
<template> <form :class="{ '--invalid': isInvalid }"> <slot /> </form> </template> <script> export default { data: () => ({ isInvalid: false, }), }; </script>
为了更新isInvalid
属性,我们需要添加一个触发的事件,可以使用 sumit
事件 ,但我更喜用 input
事件。
表单事件7个: focus, blur, input, select, change, reset, submit 等,具体详解看这篇文章:https://blog.csdn.net/qq_4379...
表单不会触发 input
事件,但我们可以使用 "事件委托"。我们将监听器附加到父元素(<form>
)上,当事件发生在它的子元素(<input>
、<select>
、<textarea>
等)上时就会被触发。
任何时候在这个组件的<slot>
中触发input
事件,表单将捕获该事件。
<template> <form :class="{ '--invalid': isInvalid }" @input="validate"> <slot /> </form> </template> <script> export default { data: () => ({ isInvalid: false, }), methods: { validate() { // 验证逻辑 } } }; </script>
验证逻辑可以是简单或复杂的。本文为了演示,用简单的方法,使用form.checkValidity()
API 来查看表单是否基于HTML验证属性而有效。
为了访问<form>
元素。可以用refs
或$el
属性。为了简单起见,本文使用$el
。
<template> <form :class="{ '--invalid': isInvalid }" @input="validate"> <slot /> </form> </template> <script> export default { data: () => ({ isInvalid: false, }), methods: { validate() { this.isInvalid = !this.$el.checkValidity() } } }; </script>
这里有一点问题。如果表单的内容改变了,会发生什么?如果一个<input>
在表单加载被添加到DOM中,会发生什么?
举个例子,我们把这个表单组件称为 "MyForm"
,在 App 中,内容如下:
// App.vue <template> <MyForm> <input v-model="showInput" id="toggle-name" name="toggle-name" type="checkbox" /> <label for="toggle-name">显示其它 input</label> <template v-if="showInput"> <label for="name">Name:</label> <input id="name" name="name" required /> </template> <button type="submit">提交</button> </MyForm> </template> <script> import Form from "./components/form.vue"; export default { name: "App", components: { MyForm: Form, }, data: () => ({ showInput: false, }), }; </script>
当App.vue
通过条件来隐藏显示某些 input
,我们的表单需要知道。在这种情况下,我们会想到在表单内容发生变化时跟踪其有效性,而不仅仅是在 input
事件或mounted
生命周期钩子上。否则,可能会显示不正确的信息。
熟悉 Vue的生命周期钩子小伙伴,这里可能会想到使用 update
来跟踪变化。理论上,这听起来不错。在实践中,它会创造一个无限的循环,然后浏览器挂了。
经过一番研究和测试,最佳解决方案是使用MutationObserver
API。它是浏览器内置的方法,提供了监视对DOM树所做更改的能力,如果节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。
它是原生的方法,所以不受限于框架。
使用时,首先使用MutationObserver
构造函数,新建一个观察器实例,同时指定这个实例的回调函数。在每次 DOM 变动后调用,这个回调都被调用。该回调函数接受两个参数,第一个是变动数组,第二个是观察器实例,将我们的 form
组件改写成如下:
<template> <form :class="{ '--invalid': isInvalid }" @input="validate"> <slot /> </form> </template> <script> export default { data: () => ({ isInvalid: false, }), mounted() { const observer = new MutationObserver(this.validate); observer.observe(this.$el, { childList: true, subtree: true, }); this.observer = observer; }, methods: { validate() { this.isInvalid = !this.$el.checkValidity(); }, }, beforeUnmount() { this.observer.disconnect(); }, }; </script> <style scoped> </style>
这里还需要使用 beforeUnmount
生命周期事件来断开observer
的连接,这会清除它所分配的任何内存。
最后,我们将isInvalid
状态传递给要访问的内容的插件槽,这也称作用域的槽,它非常有用。
<template> <form :class="{ '--invalid': isInvalid }" @input="validate"> <slot v-bind="{ isInvalid }" /> </form> </template> <script> export default { data: () => ({ isInvalid: false, }), mounted() { const observer = new MutationObserver(this.validate); observer.observe(this.$el, { childList: true, subtree: true, }); this.observer = observer; }, methods: { validate() { this.isInvalid = !this.$el.checkValidity(); }, }, beforeUnmount() { this.observer.disconnect(); }, }; </script>
通过这样的设置,可以在我们的表单组件中添加任意数量的 input
,并添加任何它需要的条件渲染逻辑。只要input
使用HTML验证属性,表单就会跟踪它是否处于有效状态。
此外,由于使用的是作用域槽,我们将表单的状态提供给父级,所以父级可以对有效性的变化做出反应。
例如,在 App.vue
]
Beginnen Sie mit der Steuerung des Formularstatus, ändern Sie eine Klasse entsprechend dem Status und füllen Sie den untergeordneten Inhalt mit <slot/>< /code>:
<template> <MyForm> <template slot:default="form"> <label for="name">Name:</label> <input id="name" name="name" required> <button type="submit" :class="{ disabled: form.isInvalid }" > Submit </button> </template> </MyForm> </template>
Um das Attribut isInvalid
zu aktualisieren, müssen wir ein ausgelöstes Ereignis hinzufügen. Sie können das Ereignis sumit
verwenden, aber ich verwende lieber das input
-Ereignis.
🎜7 Formularereignisse: Fokus, Unschärfe, Eingabe, Auswählen, Ändern, Zurücksetzen, Senden usw. Eine ausführliche Erklärung finden Sie in diesem Artikel: https://blog.csdn.net/qq_4379...🎜🎜🎜 Formulare lösen keine
Eingabeereignisse
aus, aber wir können "Ereignisdelegierte" verwenden. Wir hängen den Listener an das übergeordnete Element an (<form>
) und wenn das Ereignis an seinen untergeordneten Elementen auftritt (<input>
, <select> ;
, <textarea>
usw.) werden ausgelöst. 🎜🎜Jedes Mal, wenn das input
-Ereignis in <slot>
dieser Komponente ausgelöst wird, erfasst das Formular das Ereignis. 🎜rrreee🎜Validierungslogik kann einfach oder komplex sein. Zu Demonstrationszwecken wird in diesem Artikel eine einfache Methode zur Verwendung der API form.checkValidity()
verwendet, um anhand von HTML-Validierungsattributen zu überprüfen, ob das Formular gültig ist. 🎜🎜Um auf das <form>
-Element zuzugreifen. Sie können das Attribut refs
oder $el
verwenden. Der Einfachheit halber verwendet dieser Artikel $el
. 🎜rrreee<input>
zum DOM hinzugefügt wird? 🎜🎜Zum Beispiel nennen wir diese Formularkomponente "MyForm"
. In der App lautet der Inhalt wie folgt: 🎜rrreee🎜Wenn App.vue
die Anzeige durch Bedingungen verbirgt sind bestimmte Eingaben
s, die unser Formular kennen muss. In diesem Fall würden wir daran denken, die Gültigkeit des Formularinhalts zu verfolgen, wenn er sich ändert, und nicht nur am input
-Ereignis oder am mount
-Lebenszyklus-Hook. Andernfalls können falsche Informationen angezeigt werden. 🎜🎜Freunde, die mit den Lebenszyklus-Hooks von Vue vertraut sind, denken vielleicht darüber nach, update
zu verwenden, um Änderungen zu verfolgen. Theoretisch klingt das großartig. In der Praxis entsteht eine Endlosschleife und der Browser hängt sich auf. 🎜MutationObserver
-API. Es handelt sich um eine integrierte Methode des Browsers, die die Möglichkeit bietet, Änderungen am DOM-Baum zu überwachen. Diese API kann benachrichtigt werden, wenn Knoten hinzugefügt oder entfernt werden, sich Attribute ändern oder Textinhalte geändert werden. 🎜🎜Es handelt sich um eine native Methode, daher ist sie nicht auf Frameworks beschränkt. 🎜🎜Wenn Sie es verwenden, verwenden Sie zunächst den Konstruktor MutationObserver
, um eine neue Beobachterinstanz zu erstellen und die Rückruffunktion dieser Instanz anzugeben. Dieser Rückruf wird nach jeder DOM-Änderung aufgerufen. Die Rückruffunktion akzeptiert zwei Parameter, der erste ist das Änderungsarray und der zweite ist die Beobachterinstanz. Schreiben Sie unsere form
-Komponente wie folgt um: 🎜rrreee🎜Sie müssen hier auch beforeUnmount lifecycle-Ereignis, um den <code>Observer
zu trennen, wodurch der gesamte von ihm zugewiesene Speicher gelöscht wird. 🎜🎜Abschließend übergeben wir den Status isInvalid
an den Plugin-Slot des Inhalts, auf den wir zugreifen möchten. Dies wird auch als Scope-Slot bezeichnet und ist sehr nützlich. 🎜rrreee🎜Mit diesem Setup können wir unserer Formularkomponente eine beliebige Anzahl von Eingaben
s hinzufügen und jede benötigte bedingte Rendering-Logik hinzufügen. Solange die Eingabe
das HTML-Validierungsattribut verwendet, verfolgt das Formular, ob es sich in einem gültigen Zustand befindet. 🎜🎜 Da wir außerdem bereichsbezogene Slots verwenden, stellen wir dem übergeordneten Element den Status des Formulars zur Verfügung, sodass das übergeordnete Element auf Änderungen der Gültigkeit reagieren kann. 🎜🎜Zum Beispiel möchten wir in App.vue
die Schaltfläche „Senden“ deaktivieren, wenn das Formular ungültig ist. Sie können es so schreiben🎜rrreee🎜schön~.🎜🎜Ich hoffe, dieser Artikel kann für Ihre zukünftige Entwicklung hilfreich sein. 🎜(Teilen von Lernvideos: Web-Frontend-Entwicklung, Grundlegendes Programmiervideo)
Das obige ist der detaillierte Inhalt vonWie kann ich Vue-Slot-Änderungen überwachen? Versuchen Sie diesen Trick!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!