Reputation: 311
<span @click="showModal = $event.target.innerHtml>Tag 1</span>
<span @click="showModal = $event.target.innerHtml>Tag 2</span>
<span @click="showModal = $event.target.innerHtml>Tag 3</span>
Clicking in any of the 3 spans will make this.showModal
to have the value of each of the span content elements. But this code looks repetitive and unnecessary. I know I can create a component with v-for and have the data for the span contents somewhere else, but I want to know how to do this for very specific reasons. I'd like to have this:
<span>Tag 1</span>
<span>Tag 2</span>
<span>Tag 3</span>
And a function, e.g. in the hook mounted()
of the component, that adds the v-on directive for click
to each one of them.
Can you help me?
Thanks.
Upvotes: 0
Views: 2883
Reputation: 10729
If direct-process Dom elements, custom directive will be one option.
Vue.config.productionTip = false
let vMyDirective = {}
vMyDirective.install = function install (_Vue) {
_Vue.directive('my-directive', {
inserted: function (el, binding, vnode) {
el.addEventListener('click', () => {
_Vue.set(vnode.context, binding.value.model, el.innerHTML)
}, false)
}
})
}
Vue.use(vMyDirective)
new Vue({
el: '#app',
data() {
return {
testValues: ['label a', 'label b'],
showModal: 'nothing!!!'
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<h2>showModal: {{showModal}}</h2>
<div>
<p v-for="(item, index) in testValues" v-my-directive="{'model': 'showModal'}">Test:<span>{{item}}</span></p>
</div>
</div>
Upvotes: 0
Reputation: 311
I've finally added the listeners manually with vanilla js, in order to save code:
mounted: function() {
let spans = document.querySelectorAll('span');
spans.forEach(el => {
el.addEventListener('click', this.clickTag);
})
}
methods: {
clickTag(event) { this.showModal = event.target.innerHTML }
}
It's important not using an arrow function for mounted
because otherwise it won't bind the vue instance for this
.
Thanks for your answers.
Upvotes: 0
Reputation: 45
You could set up a method to call when the tag is clicked and pass the id of the tag that was clicked through to handle appropriately.
Assuming that you have an array of the tag text:
data: function() {
return {
tagTotal: ['Tag 1', 'Tag 2', 'Tag 3'];
}
}
Then in the HTML section:
<span v-for="tag in tagTotal" @click="methodToCall(tag)">
{{ tag }}
</span>
Then in your mounted, methods, or created section you could add:
mounted: {
methodToCall: function(tag) {
showModal = tag;
// or 'this.showModal = tag' if showModal is a part of the componenet.
}
}
Upvotes: 0
Reputation: 6075
You can add a method which is called on clicks that reads the element's HTML content.
The template:
<span @click="doStuff">Tag 1</span>
<span @click="doStuff">Tag 2</span>
<span @click="doStuff">Tag 3</span>
The method:
doStuff(e) {
this.showModal = e.target.innerHTML
}
Upvotes: 1
Reputation: 866
You could try something like this:
<template>
<span v-for="tag in tags" @click="showModal(tag)" v-text="tag"></span>
</template>
<script>
export default {
data() {
return {
tags: ['Tag 1', 'Tag 2', 'Tag 3']
}
},
methods: {
showModal(tag) {
console.log("Showing modal for tag:", tag)
}
}
}
</script>
Hope this helps!
Upvotes: 1