vue.jsobservablemutation-observers

Watch/observe number of DOM children in Vue


Given a typical Vue component with slot usage:

<template>
  <div>
    <slot></slot>
  </div>
</template>
<script>
export default {
  name: "VueComponent"
}
</script>

Is there any possible way to implement an observer/watcher that keeps track of number of DOM children inside slot? I need to know whenever a child is added/removed inside the component.


Solution

  • So what I find useful for my problem is MutationObserver. We need to attach an observer to the component after it is mounted, add callback handler and disconnect the observer before the component is destroyed (unmounted in Vue3).

    Here is an working example written in Vue 2.6

    <template>
      <div ref="container">
        <slot></slot>
      </div>
    </template>
    <script>
    export default {
      name: "VueComponent",
      data() {
        return {
          observer: null
        }
      },
      mounted() {
        this.initObserver()
      },
      beforeDestroy() {
        if (this.observer) this.observer.disconnect()
      },
      methods() {
        handleChildrenChanged() {
    
        },
        initObserver() {
          config = {
            subtree: false,
            childList: true,
            // it's better if you can detect children change by id
            // this can reduce number of updates
            // attributes: true,
            // attributeList: [ 'id' ] 
          }
          const self = this
          const callback = () => {
            self.$nextTick(() => {
              self.handleChildrenChanged()
            })
          }
          const observer = new MutationObserver(callback)
          observer.observe(this.$refs.container, config)
          this.observer = observer
        }
      }
    }
    </script>
    

    You can find another usage of MutationObserver in Vue here: https://dev.to/sammm/using-mutationobserver-and-resizeobserver-to-measure-a-changing-dom-element-in-vue-3jpd