Reputation: 395
I have a Vue app which get an html from API that contains some code like <div class="play-video"> <input type="text" class="input-1"/></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 on change events to the children inputs with the .input-1 class?
Upvotes: 1
Views: 1799
Reputation: 10192
There are two approaches that rise to the top for me:
@change="doSomething"
to the template. For this reason, I'd probably should go with option 1) unless you control the source of the templates.Whichever you do, keep malicious injections in mind.
const someHtml = '<div class="play-video"><input type="text" class="input-1"/></div>'
var app = new Vue({
el: '#app',
mounted() {
const dynamicContent = document.createElement('div');
dynamicContent.innerHTML = someHtml;
dynamicContent.querySelector('input').addEventListener('change',
e => this.inputValue = e.target.value);
this.$refs.container.appendChild(dynamicContent);
},
data() {
return {
name: 'Vue',
inputValue: ''
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>type something below then click this text</div>
<div ref="container"></div>
<div>The user entered: {{inputValue}}</div>
</div>
Upvotes: 0
Reputation: 138226
You could query the container for those inputs, and add an event handler to each:
Apply a template ref (named container
) on the container div
:
<div ref="container">
Add a watcher on content
that queries the container (via this.$refs.container.querySelectorAll()
) for <input class="input-1">
, and adds an event handler to each input. Note that the handler needs to wait until $nextTick()
, after which the v-html
directive would have had a chance to update.
export default {
watch: {
content: {
async handler(content) {
// wait til v-html directives takes effect
await this.$nextTick()
this.$refs.container
.querySelectorAll('.input-1')
.forEach((input) => input.addEventListener('change', this.onInputChange))
},
immediate: true,
},
},
methods: {
onInputChange(e) {
console.log('input change')
},
},
}
Upvotes: 3