Vue.js Vuejs v-on点击不';不要在组件内部工作

Vue.js Vuejs v-on点击不';不要在组件内部工作,vue.js,Vue.js,我使用VueJs并用它创建以下组件 var ComponentTest = { props: ['list', 'symbole'], data: function(){ return { regexSymbole: new RegExp(this.symbole), } }, template: ` <div> <ul>

我使用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: '@'
    },
});
var组件测试={
道具:['list','symbole'],
数据:函数(){
返回{
regexSymbole:newregexp(this.symbole),
}
},
模板:`
`, 方法:{ replaceSymbole:函数(名称){ 返回名称.replace(this.regexSymbole,'--'); }, 测试:功能(事件){ log('Test…'); console.log(这个$el); }, } }; var app=新的Vue({ el:“#应用程序”, 组成部分:{ “组件测试”:组件测试, }, 数据:{ 列表:[{“id”:1,“name”:“@name1”},{“id”:2,“name”:“@name2”},{“id”:3,“name”:“@name3”}], 符号:“@” }, });
这是我的html代码

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

当我单击“li”标记内的“span”标记时,没有任何附加内容

我没有任何警告和错误

单击“span”标记时如何调用组件方法“test”


如何实现这种情况下的单击事件。

您不能在馈送到
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>
    
  • 最后一个选项是手动将事件处理程序添加到范围中。我不喜欢推荐这个。当您销毁组件或列表更改时,还必须删除这些事件处理程序,否则将造成内存泄漏


如果检查生成的html,我希望您在span元素上看到一个文本v-on:click属性,对吗?是的,我看到v-on:click in all span tagVue不会解释动态创建的span标记。您可以使用纯javascript,也可以通过编程方式将Vue组件呈现到span标记中,该标记会触发单击事件。“您不能使用v-html组合模板部分,因为Vue不是基于字符串的模板引擎。相反,组件是首选的UI重用和组合的基本单元。”()。您也可以检查thx以获得答案,我无法更好地准备数据,因为我的名称字符串可能包含许多符号,是的,我不能在这种情况下使用v-html,所以我将使用纯js。@wpuser000我不理解这一点。第二个选项使用
v-html
并具有您期望的行为…我在
  • {{replaceSymbole(item.name)}}之前尝试过这个选项
  • 但是它以html“--name”呈现,所以我阅读了文档,找到了这个v-html,但是我没有很好地阅读文档,因为我无法将这个指令用于我尝试实现的目标,我只想用click listener替换span中的所有符号。例如:{name:@big name@有许多符号@“}=>big name有许多符号”
    <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>