以编程方式将v-on指令添加到DOM元素

时间:2018-07-23 22:00:57

标签: vue.js vuejs2

<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>

单击3个跨度中的任何一个将使this.showModal具有每个跨度内容元素的值。但是这段代码看起来重复且不必要。我知道我可以使用v-for创建一个组件,并将span内容的数据保存在其他地方,但是出于非常特殊的原因,我想知道如何执行此操作。我想要这个:

<span>Tag 1</span>
<span>Tag 2</span>
<span>Tag 3</span>

还有一个功能,例如在组件的钩子mounted()中,它将click的v-on指令添加到其中的每一个。

你能帮我吗?

谢谢。

5 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

<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>

希望这会有所帮助!

答案 1 :(得分:1)

您可以添加一种在单击时调用的方法,该方法可以读取元素的HTML内容。

模板:

<span @click="doStuff">Tag 1</span>
<span @click="doStuff">Tag 2</span>
<span @click="doStuff">Tag 3</span>

方法:

doStuff(e) {
  this.showModal = e.target.innerHTML
}

答案 2 :(得分:0)

您可以设置一种方法,以在单击该标签时调用该方法,并传递通过单击以正确处理的标签的ID。

假设您有一个标签文本数组:

data: function() {
  return {
    tagTotal: ['Tag 1', 'Tag 2', 'Tag 3'];
  }
}

然后在HTML部分:

<span v-for="tag in tagTotal" @click="methodToCall(tag)">
  {{ tag }}
</span>

然后在您的安装,方法或创建的部分中可以添加:

mounted: {
  methodToCall: function(tag) {
    showModal = tag;
    // or 'this.showModal = tag' if showModal is a part of the componenet.
  }
}

答案 3 :(得分:0)

如果直接处理Dom元素,custom directive将是一个选择。

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>

答案 4 :(得分:0)

为了节省代码,我终于用香草js手动添加了侦听器:

mounted: function() {
    let spans = document.querySelectorAll('span');

    spans.forEach(el => {
      el.addEventListener('click', this.clickTag);
    })
}
methods: {
    clickTag(event) { this.showModal = event.target.innerHTML }
}

重要的是不要为mounted使用箭头功能,因为否则它将不会绑定this的vue实例。

感谢您的回答。