Vue:将点击事件绑定到动态插入的内容

10

我有一个Vue应用程序,它请求一些HTML内容的API,并包含一些类似于<div class="play-video">...</div>的块。

通过Promise使用axios调用API后,将其插入到dom中,如下所示:

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

如何将点击事件绑定到具有.play-video类的子元素?只需要监听content的变化,然后运行vanilla js查询选择器来绑定它们吗?


你考虑在具有v-html属性的div中添加ref(https://vuejs.org/v2/api/#ref)吗? - mudin
1个回答

36
您可以通过添加一个@click处理程序,并使用Element.closest()来检查目标元素,从而使用一些事件委托。

```js // 示例代码 document.addEventListener('click', function(event) { if (event.target.closest('.my-class')) { // 处理点击事件 } }); ```
new Vue({
  el: "#app",
  data: () => ({
    content: null
  }),
  methods: {
    handleClick(e) {
      const elt = e.target.closest(".play-video");
      if (elt) {
        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元素本身的单击事件,而不是其任何子元素,请跳过.closest()调用并使用:

if (e.target.matches(".play-video") {
  // ...
}

查看https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#polyfill以获取浏览器兼容性和必要的填充。


非常好,谢谢。如果这是一个显而易见的问题,我很抱歉,因为很多搜索结果都在关注jQuery。 - waffl
@waffl 不用谢。我猜你找到了 jQuery 的结果,因为 jQuery 是最早真正将事件委托作为一等公民的框架之一。 - Phil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接