【问题标题】: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]

应用程序.vue
<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 方式。

谢谢。

【问题讨论】:

    标签: vue.js v-for


    【解决方案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。如果可以的话,请帮忙。再次感谢。
        猜你喜欢
        • 1970-01-01
        • 2020-05-02
        • 2018-03-06
        • 1970-01-01
        • 1970-01-01
        • 2010-12-23
        • 2019-10-21
        • 1970-01-01
        • 2019-01-31
        相关资源
        最近更新 更多