Vuejs v-on click在组件内部不起作用?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (2229)

我使用VueJs,然后用它创建以下组件。

var ComponentTest = {
    props: ['list', 'symbole'],
    data: function(){
        return {
            regexSymbole: new RegExp(this.symbole),
        }
    },
    template: `
        <div>
            <ul>
                <li v-for="item in list" 
                    v-html="replaceSymbole(item.name)">
                </li>
            </ul>
        </div>
    `,
    methods: {
        replaceSymbole: function(name){
            return name.replace(this.regexSymbole, '<span v-on:click="test">---</span>');
        },

        test: function(event){
            console.log('Test ...');
            console.log(this.$el);
        },   
    }
};


var app = new Vue({
    el: '#app',
    components: {
        'component-test': ComponentTest,
    },
    data: {
        list: [{"id":1,"name":"@ name1"},{"id":2,"name":"@ name2"},{"id":3,"name":"@ name3"}], 
        symbole: '@'
    },
});

这是我的HTML代码

<div id="app">
    <component-test :list="list" :symbole="symbole"></component-test>
</div>

当我点击“li”标签内的“span”标签时,没有任何附加内容。

我没有任何警告和任何错误。

当我点击“span”标签时,如何调用我的组件方法“test”。

如何实现此案例的点击事件。

提问于
用户回答回答于

在尝试了您的尝试之后,我假设您可以通过将click事件分配给span包装名称的标记并用空字符串替换symbole 来实现相同的行为并产生以下解决方案:

     <li v-for="item in list"  >
        ---<span>{{replaceSymbole(item.name)}}</span>
     </li> 
     replaceSymbole: function(name){
        return name.replace(this.regexSymbole, '');
    }

var ComponentTest = {
    props: ['list', 'symbole'],
    data: function(){
        return {
            regexSymbole: new RegExp(this.symbole),
        }
    },
    template: `
        <div>
            <ul>
                <li v-for="item in list" 
                    >
                   ---<span v-on:click="test">{{replaceSymbole(item.name)}}</span>
                </li>
            </ul>
        </div>
    `,
    methods: {
        replaceSymbole: function(name){
            return name.replace(this.regexSymbole, '');
        },

        test: function(event){
            console.log('Test ...');
            console.log(this.$el);
        },   
    }
};


var app = new Vue({
    el: '#app',
    components: {
        'component-test': ComponentTest,
    },
    data: {
        list: [{"id":1,"name":"@ name1"},{"id":2,"name":"@ name2"},{"id":3,"name":"@ name3"}], 
        symbole: '@'
    },
});

<!DOCTYPE html>
<html>

<head>
  <meta name="description" content="Vue.delete">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.min.js"></script>
</head>

<body>
  <div id="app">
  <component-test :list="list" :symbole="symbole"></component-test>
  </div>
 </body>
用户回答回答于

您不能在您提供的字符串中使用vue指令v-html。它们不被解释,而是最终作为实际属性。你有几个选择:

  • 更好地准备数据,以便使用普通模板。例如,您可以将数据准备为对象:{ linkText: '---', position: 'before', name: 'name1' },然后根据位置进行渲染。我认为这是迄今为止最好的解决方案。 <template> <div> <ul> <li v-for="(item, index) in preparedList" :key="index"> <template v-if="item.position === 'before'"> <span v-on:click="test">{{ item.linkText }}</span> {{ item.name }} </template> <template v-else-if="item.position === 'after'"> {{ item.name }} <span v-on:click="test">{{ item.linkText }}</span> </template> </li> </ul> </div> </template> <script> export default { props: ["list", "symbole"], computed: { preparedList() { return this.list.map(item => this.replaceSymbole(item.name)); } }, methods: { replaceSymbole: function(question) { if (question.indexOf("@") === 0) { return { linkText: "---", position: "before", name: question.replace("@", "").trim() }; } else { return { linkText: "---", position: "after", name: question.replace("@", "").trim() }; } }, test: function(event) { console.log("Test ..."); console.log(this.$el); } } }; </script>
  • 您可以将click处理程序放在周围的li上,并过滤事件。您的点击处理程序的第一个参数是MouseEvent被触发的。 <template> <div> <ul> <li v-for="item in list" :key="item.id" v-on:click="clickHandler" v-html="replaceSymbole(item.name)"> </li> </ul> </div> </template> <script> export default { props: ["list", "symbole"], data() { return { regexSymbole: new RegExp(this.symbole) }; }, computed: { preparedList() { return this.list.map(item => this.replaceSymbole(item.name)); } }, methods: { replaceSymbole: function(name) { return name.replace( this.regexSymbole, '<span class="clickable-area">---</span>' ); }, test: function(event) { console.log("Test ..."); console.log(this.$el); }, clickHandler(event) { const classes = event.srcElement.className.split(" "); // Not something you do not want to trigger the event on if (classes.indexOf("clickable-area") === -1) { return; } // Here we can call test this.test(event); } } }; </script>
  • 您的最后一个选项是手动将事件处理程序添加到您的跨度。我没有!!! 推荐这个。当您销毁组件或列表更改时,您还必须删除这些事件处理程序,否则您将创建内存泄漏。

扫码关注云+社区

领取腾讯云代金券