最近,我需要在组件的内容(插槽、子组件等)发生变化时更新组件的状态。对于上下文,它是一个表单组件,用于跟踪其输入的有效性状态。下面的代码片段以OptionsAPI格式编写,但除非另有说明,否则适用于Vue2和Vue2。从控制表单的状态开始,根据状态修改一个类,填充子内容:为了更新isInvalid属性,我们需要添加一个触发事件,可以使用sumit事件,但我更喜欢使用input事件。表单事件有7个:focus,blur,input,select,change,reset,submit等,具体见这篇文章:https://blog.csdn.net/qq_43797996/article/details/103066452表单不会触发输入事件,但我们可以使用“事件委托”。我们将侦听器附加到父元素(验证逻辑可以简单也可以复杂。本文为了演示,使用form.checkValidity()API以简单的方式基于HTML验证属性检查表单是否有效。为了访问这里有个小问题。如果表单内容发生变化会怎样?如果在表单加载时将添加到DOM会发生什么?比如我们把这个表单组件命名为“MyForm”,在App中,内容如下:://App.vue显示其他输入名称:提交当App.vue使用条件隐藏和显示某些输入,我们的表单需要知道。在这种情况下,我们会考虑在表单内容发生变化时跟踪其有效性,而不仅仅是在输入事件或挂载的生命周期钩子上。否则,可能会显示不正确的信息。熟悉Vue的生命周期钩子的朋友,可能会想到使用update来跟踪变化。从理论上讲,这听起来不错。实际上,它创建了一个无限循环,然后浏览器挂起。解决方法经过一些研究和测试,最好的解决方案是使用MutationObserverAPI。它是一种浏览器内置方法,可以监视对DOM树所做的更改。如果节点增加或减少,属性改变,或者文本内容改变,都可以通知这个API。它是一种本机方法,因此不限于框架。使用时,首先使用MutationObserver构造函数创建一个新的观察者实例,并指定该实例的回调函数。在每次DOM更改后调用,调用此回调。回调函数接受两个参数,第一个是变化数组,第二个是观察者实例。重写我们的表单组件如下:data:()=>({isInvalid:false,}),mounted(){constobserver=newMutationObserver(this.validate);observer.observe(this.$el,{childList:true,subtree:true,});this.observer=observer;},方法:{validate(){this.isInvalid=!this.$el.checkValidity();},},beforeUnmount(){this.observer.disconnect();},};在这里您还需要使用beforeUnmount生命周期事件来断开观察者,这将清除它分配的所有内存。最后,我们将isInvalid状态传递给要访问的内容的插件插槽,这也称为作用域插槽,它非常有用。有了这个设置,我们可以向我们的表单组件添加任意数量的输入,并添加它需要的任何条件渲染逻辑。只要输入使用HTML验证属性,表单就会跟踪它是否处于有效状态。此外,由于我们使用的是作用域插槽,我们将表单的状态提供给父级,因此父级可以对有效性的变化做出反应。比如在App.vue中,我们想在表单无效时“禁用”提交按钮,那么我们可以这样写Name:提交不错~。希望本文能对您以后的发展有所帮助。