vue判断组件是否显示_在Vue.js中,组件可以检测插槽内容何时更改

We have a component in Vue which is a frame, scaled to the window size, which contains (in a ) an element (typically or ) which it scales to fit the frame and enables pan and zoom on that element.

The component needs to react when the element changes. The only way we can see to do it is for the parent to prod the component when that happens, however it would be much nicer if the component could automatically detect when the element changes and react accordingly. Is there a way to do this?

解决方案

To my knowledge, Vue does not provide a way to do this. However here are two approaches worth considering.

Watching the Slot's DOM for Changes

Use a MutationObserver to detect when the DOM in the changes. This requires no communication between components. Simply set up the observer during the mounted callback of your component.

Here's a snippet showing this approach in action:

Vue.component('container', {

template: '#container',

data: function() {

return { number: 0, observer: null }

},

mounted: function() {

// Create the observer (and what to do on changes...)

this.observer = new MutationObserver(function(mutations) {

this.number++;

}.bind(this));

// Setup the observer

this.observer.observe(

$(this.$el).find('.content')[0],

{ attributes: true, childList: true, characterData: true, subtree: true }

);

},

beforeDestroy: function() {

// Clean up

this.observer.disconnect();

}

});

var app = new Vue({

el: '#app',

data: { number: 0 },

mounted: function() {

//Update the element in the slot every second

setInterval(function(){ this.number++; }.bind(this), 1000);

}

});

.content, .container {

margin: 5px;

border: 1px solid black;

}

I am the container, and I have detected {{ number }} updates.

I am the content, and I have been updated {{ number }} times.

Using Emit

If a Vue component is responsible for changing the slot, then it is best to emit an event when that change occurs. This allows any other component to respond to the emitted event if needed.

To do this, use an empty Vue instance as a global event bus. Any component can emit/listen to events on the event bus. In your case, the parent component could emit an "updated-content" event, and the child component could react to it.

Here is a simple example:

// Use an empty Vue instance as an event bus

var bus = new Vue()

Vue.component('container', {

template: '#container',

data: function() {

return { number: 0 }

},

methods: {

increment: function() { this.number++; }

},

created: function() {

// listen for the 'updated-content' event and react accordingly

bus.$on('updated-content', this.increment);

},

beforeDestroy: function() {

// Clean up

bus.$off('updated-content', this.increment);

}

});

var app = new Vue({

el: '#app',

data: { number: 0 },

mounted: function() {

//Update the element in the slot every second,

// and emit an "updated-content" event

setInterval(function(){

this.number++;

bus.$emit('updated-content');

}.bind(this), 1000);

}

});

.content, .container {

margin: 5px;

border: 1px solid black;

}

I am the container, and I have detected {{ number }} updates.

I am the content, and I have been updated {{ number }} times.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值