在 Vue.js 中,组件可以检测槽内容何时发生变化 [英] In Vue.js can a component detect when the slot content changes
问题描述
我们在 Vue 中有一个组件,它是一个框架,缩放到窗口大小,其中包含(在
中)一个元素(通常是 code> 或
),它会缩放以适应框架,并在该元素上启用平移和缩放.
组件需要在元素发生变化时做出反应.我们可以看到这样做的唯一方法是让父级在发生这种情况时刺激组件,但是如果组件可以自动检测
元素何时发生变化并做出反应,那就更好了因此.有没有办法做到这一点?
据我所知,Vue 没有提供解决方案.不过这里有两种方法值得考虑.
查看 Slot 的 DOM 是否有变化
使用 MutationObserver 来检测
变化.这不需要组件之间的通信.只需在组件的 mounted
回调期间设置观察者.
下面的代码片段展示了这种方法的实际效果:
Vue.component('container', {模板:'#container',数据:函数(){返回{数量:0,观察者:空}},安装:功能(){//创建观察者(以及如何处理更改...)this.observer = new MutationObserver(function(mutations) {this.number++;}.bind(this));//设置观察者this.observer.observe($(this.$el).find('.content')[0],{ 属性:true,childList:true,characterData:true,子树:true });},beforeDestroy:函数(){//清理this.observer.disconnect();}});var app = new Vue({el: '#app',数据:{数量:0},安装:功能(){//每秒更新slot中的元素setInterval(function(){ this.number++; }.bind(this), 1000);}});
.content, .container {边距:5px;边框:1px纯黑色;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script><模板 id="容器"><div class="容器">我是容器,我检测到 {{ number }} 更新.<div class="content"><slot></slot></div>
模板><div id="应用程序"><容器>我就是内容,我已经更新了{{ number }}次.</容器>
使用发射
如果 Vue 组件负责更改槽位,那么最好 emit发生这种变化时的事件.这允许任何其他组件在需要时响应发出的事件.
为此,请使用一个空的 Vue 实例作为全局事件总线.任何组件都可以在事件总线上发出/监听事件.在您的情况下,父组件可以发出更新内容"事件,子组件可以对其做出反应.
这是一个简单的例子:
//使用一个空的 Vue 实例作为事件总线var bus = new Vue()Vue.component('容器', {模板:'#container',数据:函数(){返回{数量:0}},方法: {增量:function() { this.number++;}},创建:函数(){//监听 'updated-content' 事件并做出相应的反应bus.$on('更新内容', this.increment);},beforeDestroy:函数(){//清理bus.$off('更新内容', this.increment);}});var app = new Vue({el: '#app',数据:{数量:0},安装:功能(){//每秒更新槽中的元素,//并发出更新内容"事件设置间隔(函数(){this.number++;bus.$emit('更新内容');}.bind(this), 1000);}});
.content, .container {边距:5px;边框:1px纯黑色;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script><模板 id="容器"><div class="容器">我是容器,我检测到 {{ number }} 更新.<div class="内容"><插槽></插槽>
模板><div id="应用程序"><容器>我就是内容,我已经更新了{{ number }}次.</容器>