VueJS:使用 v-html 来 appendChild 不起作用,为啥?
Posted
技术标签:
【中文标题】VueJS:使用 v-html 来 appendChild 不起作用,为啥?【英文标题】:VueJS: Using v-html to appendChild not working, why?VueJS:使用 v-html 来 appendChild 不起作用,为什么? 【发布时间】:2020-04-17 06:36:36 【问题描述】:在这个简单的codesandbox demo 中,html 元素存储在一个数据数组中,v-html
绑定到一个 div 以将这些元素呈现为该 div 的子元素。但它不起作用,当添加新元素时,元素不会被渲染,而是显示[object HTMLParagraphElement]
。
<template>
<div id="app">
<child />
</div>
</template>
<script>
import child from "./components/child";
export default
name: "App",
components:
child
;
</script>
孩子.vue
<template>
<div>
<button @click="addNewEl">Add New Element</button>
<div v-for="el in elList" v-html="el"></div>
</div>
</template>
<script>
export default
name: "Child",
data()
return
elList: []
;
,
methods:
addNewEl()
var para = document.createElement("P"); // Create a <p> node
var t = document.createTextNode("This is a paragraph."); // Create a text node
para.appendChild(t); // Append the text to <p>
this.elList.push(para);
,
created()
this.addNewEl();
;
</script>
谁能告诉我我做错了什么,并展示将孩子附加到父母身上的正确 Vue 方式。
谢谢。
【问题讨论】:
【参考方案1】:在 Vue 中直接向 DOM 添加元素不是必需的,而且是非常糟糕的做法。这是“Vue方式”的做法:
<template>
<div>
<button @click="addNewPara">Add New Para</button>
<div>
<p v-for="(p, index) in para" :key="index"> p </p>
</div>
</div>
</template>
<script>
export default
name: "Child",
data()
return
para: ['This is a paragraph 1', 'This is a paragraph 2'],
;
,
methods:
addNewPara()
this.para.push(`This is a paragraph $this.para.length + 1`)
;
</script>
【讨论】:
【参考方案2】:您可以使用以下方法修改方法:
addNewEl()
this.elList.push("<p>This is a paragraph.</p>");
【讨论】:
【参考方案3】:由于v-html
期望将字符串解析为 HTML,因此在以编程方式呈现 HTML 元素时不能使用此指令。
改用元素的outerHTML
属性。 Reference
<template>
<div>
<button @click="addNewEl">Add New Element</button>
<div v-for="el in elList" v-html="el.outerHTML"></div>
</div>
</template>
【讨论】:
您好,感谢您的回答。通过el.outerHTML
添加el
实际上会删除附加到该元素的所有eventListener(从现有元素中删除并添加/推送到elList
数组时。有没有办法在以vue 方式进行时保留eventListeners。谢谢
@appu 你能展示你如何添加事件监听器的代码吗?
这里是使用v-html=el.outerHTML
的实际问题的demo。在演示中,图像是由Vue2Dropzone
在 childZones 中手动添加的。 fileWasAdded
(event) 在 img 添加到 dropzone 时触发。在这里,我创建了一个新的 elem,将 dropzones file.previewTemplate
添加到它并将 elem 添加到数据数组中,导致 previewElements
计算进行评估(这种方式会丢失原始点击事件)。另一种方法是 appendsChild 'file.previewTemplate' 直接到 DOM $refs.childZoneRef (preserve click binding, but this isnt vue way). See
slide-template.vue`
您有没有机会阅读我的最后一条评论或查看此demo。如果可以的话,请帮忙。再次感谢。以上是关于VueJS:使用 v-html 来 appendChild 不起作用,为啥?的主要内容,如果未能解决你的问题,请参考以下文章
VueJS根据for循环中的变量加载SVG文件,使用v-html给出[object Module]
在 vuejs2 数据中动态插入子组件(无需 $compile 或滥用 v-html)