Vue Watch для смены класса - PullRequest
       27

Vue Watch для смены класса

0 голосов
/ 12 октября 2018

Я бы хотел послушать смену класса.Если кнопка получила «полностью в окне просмотра», то для запуска нажмите.$( "button.in-viewport.fully-in-viewport" ).trigger( "click" ); Найдено для многих других опций, но ничего не изменилось.Любые предложения, пожалуйста?

1 Ответ

0 голосов
/ 13 октября 2018

Вы можете использовать MutationObserver для наблюдения за изменениями класса и реагировать в соответствии с новым значением класса:

  1. Добавить ref к элементудля наблюдения:

    <button ref="myButton">foo</button>
    
  2. Создайте метод для обработки наблюдаемых изменений:

    methods: {
      onClassChange(classAttrValue) {
        const classList = classAttrValue.split(' ');
        if (classList.includes('fully-in-viewport')) {
          console.log('has fully-in-viewport');
        }
      }
    }
    
  3. Создайте MutationObserver, который наблюдает изменения вclass атрибут элемента ref, который будет вызывать метод, определенный выше:

    mounted() {
      this.observer = new MutationObserver(mutations => {
        for (const m of mutations) {
          const newValue = m.target.getAttribute(m.attributeName);
          this.$nextTick(() => {
            this.onClassChange(newValue, m.oldValue);
          });
        }
      });
    
      this.observer.observe(this.$refs.myButton, {
        attributes: true,
        attributeOldValue : true,
        attributeFilter: ['class'],
      });
    },
    beforeDestroy() {
      this.observer.disconnect();
    }, 
    

Vue.component('foo', {
  template: `<button ref="myButton" class="foo" @click="onClick">foo</button>`,
  mounted() {
    this.observer = new MutationObserver(mutations => {
      for (const m of mutations) {
        const newValue = m.target.getAttribute(m.attributeName);
        this.$nextTick(() => {
          this.onClassChange(newValue, m.oldValue);
        });
      }
    });

    this.observer.observe(this.$refs.myButton, {
      attributes: true,
      attributeOldValue : true,
      attributeFilter: ['class'],
    });
  },
  beforeDestroy() {
    this.observer.disconnect();
  },
  methods: {
    onClassChange(classAttrValue) {
      const classList = classAttrValue.split(' ');
      if (classList.includes('fully-in-viewport')) {
        this.$refs.myButton.click();
      }
    },
    onClick() {
      requestIdleCallback(() => {
        alert('foo clicked');
      });
    }
  }
});

new Vue({
  el: '#app',
  data: () => ({
    active: false
  }),
})
.foo {
  margin: 20px;
}
<script src="https://unpkg.com/vue@2.5.17"></script>

<div id="app">
  <div>
    <label>
      <input type="checkbox" @change="active = !active">
      <code>.fully-in-viewport</code> class
    </label>
  </div>
  <foo :class="{'fully-in-viewport': active}"></foo>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...