首页 > 解决方案 > Vue - 动态创建使用例如 v-on:click 的 div

问题描述

我有类似的东西:

<div v-if="dataIsLoaded" v-for="(line, index) in json.data" v-on:dblclick="edit(index)" v-html="test(index)">

</div>

并且 test(index) 返回 html-ish 字符串:

<div id=${index} v-on:click="remove(index)"></div>

我怎样才能让它工作?

我的目标是:

如果 dataIsLoaded == true,则 json.data 中的 foreach (line, index) 执行

test(index) 并将其输出返回到该容器并将其显示为 html。

同时,来自 test(index) 的输出可以通过字符串定义不同的函数/事件(如上所示)。

标签: javascriptvue.jsvuejs2frontend

解决方案


你为什么在这里使用v-htmlv-html真的应该只在非常具体和有限的情况下才需要;我认为它不适用于这里。该字符串<div id=${index} v-on:click="remove(index)"></div>不是纯 HTML,它是一个 Vue 模板字符串,所以它不起作用v-html也容易受到 XSS 攻击;总而言之,我说像瘟疫一样避免它。

改为执行以下操作:

<template v-if="dataIsLoaded">
  <div v-for="(line, index) in json.data" @dblclick="edit(index)">
    <!-- Type1 -->
    <div v-if="line.type === 'Type1'" :id="index" @click="remove(index)"></div>

    <!-- Type2 -->
    <div v-else-if="line.type === 'Type2'">...</div>
  </div>
</template>

type在每个线条对象上添加了属性作为鉴别器,以确定应该为线条使用哪个模板。

此外,我将 div 提升v-if="dataIsLoaded"<template>div 上方,因为v-if对 div 生成的每个 div 进行评估,v-for并且条件不依赖于孩子,因此不需要为每个孩子重复它(一个小的优化)。

如果您不喜欢有很多v-ifand v-else-if(模板中的一种“switch”语句)的想法,那么您可以使用<component :is="...">

<div v-for="(line, index) in json.data" @dblclick="edit(index)">
  <component :is="line.type" :id="index"/>
</div>
import Type1 from './type1.vue'
import Type2 from './type2.vue'

export default {
  components: {
    Type1,
    Type2
  }
}

推荐阅读