Vue: привязать событие клика к динамически вставляемому контенту

У меня есть приложение Vue, которое запрашивает HTML-код из API, который содержит некоторые блоки, такие как <div class="play-video">...</div>

Вызывая API с помощью axios через обещание, оно вставляется в dom примерно так:

<div v-if="content" v-html="content"></div>

Как я могу привязать события кликов к детям с .play-video учебный класс? Это просто вопрос наблюдения за content изменить, а затем запустить селекторы запросов vanilla js для их привязки?

1 ответ

Решение

Вы можете использовать делегирование некоторых событий, добавив @click обработчик и проверка целевого элемента с помощью Element.matches()

new Vue({
  el: '#app',
  data: {
    content: null
  },
  methods: {
    handleClick(e) {
      if (e.target.matches('.play-video, .play-video *')) {
        console.log('Got a click on .play-video or a child element')
      }
    }
  },
  mounted () {
    // simulate loading content
    setTimeout(() => {
      this.content = `
        <div>
          <p>Some other element</p>
          <button>I'm not part of <code>.play-video</code></button>
          <div class="play-video">
            <p><button>Click me, I am!</button></p>
          </div>
        </div>
        `
    }, 1000)
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<div id="app">
  <div v-if="content" v-html="content" @click="handleClick"></div>
  <p v-else>Loading...</p>
</div>

Если вы хотите поймать события клика на .play-video сам элемент, а не его дочерние элементы, измените селектор на просто '.play-video',

См. https://developer.mozilla.org/en-US/docs/Web/API/Element/matches для совместимости с браузером и при необходимости заполните polyfill.

Другие вопросы по тегам