简体   繁体   中英

Vue: Bind click event to dynamically inserted content

I have a Vue app which requests some html from an API that contains some blocks like <div class="play-video">...</div>

Calling the API with axios via a promise, it is inserted into the dom something like:

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

How can I bind click events to the children with the .play-video class? Is it just a matter of watching for content to change, and then running vanilla js query selectors to bind to them?

You can use some event delegation by adding a @click handler and checking the target element using 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> 

If you only want to catch click events on the .play-video element itself and not any of its children, change the selector to just '.play-video' .

See https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill for browser compatibility and a polyfill if required.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM