动态插入字符串上的 Vue 事件处理程序不起作用

Posted

技术标签:

【中文标题】动态插入字符串上的 Vue 事件处理程序不起作用【英文标题】:Vue event handler on dynamically inserted string does not work 【发布时间】:2018-04-22 12:21:38 【问题描述】:

这是我的代码:

<template>
    <div>      
      <div v-html="data"></div> <button v-on:click="replace">Click Me to replace div contents</button>
    </div>
</template>
<script>
export default 
  data() 
    return 
      data: "I will be replaced once you click on button"
    
  ,
  methods: 
    clickMe() 
      alert("worked");
    ,
    replace()
      this.data = "Why does click me not work? It is loaded from server via ajax <a href v-on:click.prevent='clickMe'>Click Me</a>";
    
  
;
</script>

在这里,如果我点击 Click Me to replace div contents,内容会被替换,但事件处理程序 clickMe 不会触发。此数据将来自服务器,我需要编译此字符串并在 Vue 的上下文中使用它,以便 Vue 可以处理事件等。

如何让从服务器下载的动态字符串工作?我正在使用 Vue 2。

【问题讨论】:

点击按钮后你打算看到什么? @samayo:感谢您的回复。当单击“单击我替换 div 内容”时,我会看到 Why does click me not work? It is loaded from server via ajax &lt;a href v-on:click.prevent='clickMe'&gt;Click Me&lt;/a&gt; 这是正确的,但是现在当我单击 单击我 时,我看不到警报。那是我的问题。 【参考方案1】:

v-html 未编译为 Vue 模板。来自文档:

请注意,内容是以纯 HTML 形式插入的——它们不会被编译为 Vue 模板。如果您发现自己尝试使用 v-html 编写模板,请尝试改用组件来重新考虑解决方案。

见:https://vuejs.org/v2/api/#v-html

【讨论】:

谢谢。那么您知道解决此问题的潜在方法吗? 你必须给它一个模板 @samayo:我无法跟上。可以分享一下代码吗? @TimLiberty 好的,检查我的答案【参考方案2】:

您不能从 html 字符串呈现 VueJS 代码。

你可以使用 v-if 解决这个问题

<div>
<div v-if="data">I will be replaced once you click on button</div> 
<div v-else>Why does click me not work? It is loaded from server via ajax <a href @click.prevent='clickMe'>Click Me</a></div>
<button @click="replace">Click Me to replace div contents</button>
</div>

<script>
export default 
  data() 
    return 
      data: true
    
  ,
  methods: 
    clickMe() 
      alert("worked");
    ,
    replace()
      this.data = !this.data;
    
  
;

您可以从字符串调用普通的 javascript 函数,但不能调用 vuejs 函数,因此 onclick 事件也可以工作。

【讨论】:

完整的字符串与@click 一起从服务器返回,因此此解决方案将不起作用。 如提及vuejs.org/v2/api/#v-html“内容以纯 HTML 形式插入 - 它们不会被编译为 Vue 模板”。您需要使用组件并将服务器返回的字符串作为模板传递。【参考方案3】:

由于 v-html 没有被编译,你必须创建一个像这样的迷你组件来解决这个问题:

new Vue(
  el: '#app',
  data () 
    return 
      data: ``
    
  ,
  
  computed: 
    compiledData () 
      return 
      	template: `<p>$this.data</p>`
      
    
  ,
  
  methods: 
    replace () 
       this.data = `Now click on me <a href='#' @click.prevent='alert("yo")'> here </a>`
    
  
)
<script src="https://unpkg.com/vue@2.5.3/dist/vue.min.js"></script>


<div id="app">
  <component :is="compiledData" ></component>
  <button v-on:click="replace">Click Me to replace div contents</button>
</div>

上面的代码编译了字符串内容,因此你可以按预期运行/执行函数

【讨论】:

这是一个很好的解决方案。 惊人的三昧耶。你太棒了!【参考方案4】:

其他使用 Vue 组件的解决方案(codepen):

<script src="https://unpkg.com/vue"></script>
<div id="app">      
  <div id="someId"></div> <button v-on:click="replace">Click Me to replace div contents</button>
  <component :is="currentView"></component>
</div>

<script>
let app = new Vue(
  el: '#app',
  data: 
    currentView: null   
  ,
  methods:
    replace: function()
      var templateFromServer = getTemplate();
       var comp=Vue.component('template-from-server', 
          template: templateFromServer,
          methods:
            clickMe:function ()
              console.log("click");
                        
          
        );   
      this.currentView = comp;
       
  
);

function getTemplate()
  return "<a href v-on:click.prevent='clickMe'>Click Me</a>"

</script>

【讨论】:

以上是关于动态插入字符串上的 Vue 事件处理程序不起作用的主要内容,如果未能解决你的问题,请参考以下文章

带有动态模板的 Vue.js 组件(例如事件处理程序)

jqm listview上的onclick事件不起作用?

UWP 上的 Accelerometer.Shaken 事件不起作用,有啥解决方案吗?

Vue JS:使用基于提供的索引的 splice() 方法删除数组中动态渲染的组件,不起作用

单击 div 上的事件以获取 innerText 值并使用事件总线 $emit 到另一个组件不起作用

webkit iOS 5上的自定义Javascript事件不起作用