Vue——vue2监听元素style变化

发布时间 2024-01-03 00:18:27作者: 。思索

前言

纯粹是为了偷懒,不想再安装swiper来渲染,直接改造下element-ui的走马灯,实现类似的效果,最主要的是后续会迭代到vue3,所以这里临时的实现下即可;

内容

元素绑定ref

给需要监听的元素添加ref,这里是ref="carouse"

<div
                    v-for="(nodes, index) in form.bricks"
                    :key="index"
                    :class="activeIndex === index? 'active' : ''"
                  >
                    <component
                      :is="nodes.els.el"
                      :type="nodes.els.type"
                      :autoplay="!!nodes.auto_play"
                      :src="nodes.els.src"
                      arrow="never"
                      :height="computedHeight(nodes)"
                      @click.native="handleClickNode({...nodes, ...{index: index}})"
                    >
                      <el-carousel-item
                        v-for="(item, i) in nodes.group_content"
                        :key="i"
                        ref="carouse"
                      >
                        <el-image
                          :src="item.src"
                          :class="['carousel'].includes(nodes.group_type)? 'margin-right-xxl' : ''"
                        />
                      </el-carousel-item>
                    </component>
                  </div>

监听元素

leftNav 为左边侧边栏数据,当点击添加的时候会塞入相应的数据,监听该数据变化即可;
主要还是基于MutationObserver来实现监听;

watch: {
    leftNav: {
      handler(val) {
        if (val.group_type !== 'carousel') return ''
        this.$nextTick(() => {
          const elements = this.$refs.carouse
          elements.forEach((element, index) => {
            const observer = new MutationObserver((mutationsList) => {
              for (const mutation of mutationsList) {
                if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
                  if (element.translate > 0) element.translate = 350
                }
              }
            })
            const config = { attributes: true, attributeFilter: ['style'] }
            observer.observe(element.$el, config)
          })
        })
      },
      deep: true
    }
  },