动态插入字符串上的 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 <a href v-on:click.prevent='clickMe'>Click Me</a>
这是正确的,但是现在当我单击 单击我 时,我看不到警报。那是我的问题。
【参考方案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 事件处理程序不起作用的主要内容,如果未能解决你的问题,请参考以下文章
UWP 上的 Accelerometer.Shaken 事件不起作用,有啥解决方案吗?
Vue JS:使用基于提供的索引的 splice() 方法删除数组中动态渲染的组件,不起作用