Vue.js v-on Click在组件内部不起作用

时间:2018-10-22 19:07:15

标签: vue.js

我使用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”。

在这种情况下如何实现点击事件。

1 个答案:

答案 0 :(得分:1)

您不能在输入到v-html的字符串中使用vue指令。它们不会被解释,而是最终成为实际属性。您有几种选择:

  • 更好地准备数据,因此可以使用常规模板。例如,您将数据准备为对象:{ 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>
    
  • 您可以将点击处理程序放在周围的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>
    
  • 您的最后一个选择是将事件处理程序手动添加到您的范围中。我不!!! 推荐此。您必须还必须在销毁组件或列表更改时删除这些事件处理程序,否则会造成内存泄漏。

Edit Vue Template