简体   繁体   English

在Vue.js中调整元素大小时如何触发事件?

[英]How to trigger an event when element is resized in Vue.js?

Currently I trigger an event to take the same height of the current element when the component is mounted, however this doesn't always work since it is sent once and if the element is resized it won't get sent again.目前,我在安装组件时触发一个事件以获取与当前元素相同的高度,但这并不总是有效,因为它只发送一次,并且如果调整了元素的大小,它将不会再次发送。 Also I need to put a timeout since sometimes the chart in the componenet change sthe height after the ajax call.另外我需要设置一个超时,因为有时组件中的图表会在 ajax 调用后改变高度。

How do I send this event ANYTIME the height of the current element is changed?如何在当前元素的高度发生变化时发送此事件?

This is what I am currently doing:这就是我目前正在做的事情:

    mounted: function() {
        setTimeout(function() {
            this.$emit('resize', this.$el.offsetHeight);
        },1000);
    }

There is more Vue style solution based on ResizeObserver , but not supported in all browsers - yet还有更多基于ResizeObserverVue 风格解决方案,但并非所有浏览器都支持 - 还

DOC : https://caniuse.com/#feat=resizeobserver文档: https : //caniuse.com/#feat=resizeobserver

Examplum示例

data () {
  return {
    ro: null,
  }
},

methods: {
  onResize () {
    this.$emit('resize', this.$refs.myElement.offsetHeight)
  },
},

mounted () {
  this.ro = new ResizeObserver(this.onResize)
  this.ro.observe(this.$refs.myElement)
},

beforeDestroy () {
  this.ro.unobserve(this.$refs.myElement)
}

Until ResizeObserver becomes standard, you can use MutationObserver to keep track of the element's size.在 ResizeObserver 成为标准之前,您可以使用 MutationObserver 来跟踪元素的大小。 Codepen link代码笔链接

 new Vue({ el: "#app", data() { return { width: null, height: null, observer: null }; }, mounted() { //get initial dimensions. Mutation observer will observe mutations only const box = this.$refs.box, boxSize = box.getBoundingClientRect(); this.width = Math.trunc(boxSize.width) + "px"; this.height = Math.trunc(boxSize.height) + "px"; // initialize the observer on mount this.initObserver(); }, //disconnect the observer before destroy beforeDestroy() { if (this.observer) this.observer.disconnect(); }, methods: { initObserver() { const box = this.$refs.box, vm = this, config = { attributes: true }; // create the observer const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { // check if the mutation is attributes and update the width and height data if it is. if (mutation.type === "attributes") { let { width, height } = box.style; vm.width = width; vm.height = height; } }); }); // observe element's specified mutations observer.observe(box, config); // add the observer to data so we can disconnect it later this.observer = observer; } } });
 .box { text-align: center; font-family: Arial; box-sizing: border-box; width: 150px; height: 150px; border: 2px solid red; padding: 10px; margin: 0 auto; resize: both; overflow: auto; } .size { color: #2a9966; font-weight: 600; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <!-- more info on refs: https://vuejs.org/v2/api/#ref --> <div class=" box" ref="box"> <h4>Resize Me</h4> <p> <span>width: </span><span class="size">{{ width }}</span> </p> <p> <span>height: </span><span class="size">{{ height }}</span> </p> </div> </div>

I've had some issues getting ResizeObserver to work in a Vue2 TypeScript project.我在让ResizeObserver在 Vue2 TypeScript 项目中工作时遇到了一些问题。 Two approaches worked with (AFAICT) identical results:两种方法使用(AFAICT)相同的结果:

  • Using the resize-observer-polyfill (which essentially wraps MutationObserver ).使用resize-observer-polyfill (它本质上包装了MutationObserver )。 This required an import ResizeObserver from 'resize-observer-polyfill' in my component.这需要从我的组件中import ResizeObserver from 'resize-observer-polyfill'

  • Installing the @types/resize-observer-browser npm package, based on this answer , and adding an entry to my tsconfig.json :根据这个答案安装@types/resize-observer-browser npm 包,并在我的tsconfig.json中添加一个条目:

     { "compilerOptions": { ... "types": [ ... "resize-observer-browser" ] } }

    This second approach didn't require any additional import and is the solution I'm favouring.第二种方法不需要任何额外的导入,是我喜欢的解决方案。

Both approaches offer the same ResizeObserver API, eg两种方法都提供相同的ResizeObserver API,例如

this.resizeObserver = new ResizeObserver((entries, observer) => {
    log("Resize called", entries, observer)
})
this.resizeObserver.observe(this.$refs.canvas as Element)

(note: only tested in Chrome 88, Feb 2021) (注:仅在 2021 年 2 月的 Chrome 88 中测试)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM