如何在 Vue.js 中使用 v-for 动态创建新的 div?

Posted

技术标签:

【中文标题】如何在 Vue.js 中使用 v-for 动态创建新的 div?【英文标题】:How to dynamically create a new div using v-for in Vue.js? 【发布时间】:2018-01-25 00:10:29 【问题描述】:

我想根据数组中存在的元素数量动态创建 div。 div 包含由 ProgressBar.js 创建的 html 元素。

这是 Vue.js 代码

import ProgressBar from 'progressbar.js'
var bar;

export default 
    data() 
        return 
            fitness: ['Run', 'Cycle'],
            val: 0.65
        
    ,

    mounted()
        this.showProgressBar(this.val);
    ,


    created: function() 

    ,

    methods:
         showProgressBar: function(val)
            new ProgressBar.Circle('#container',
                trailColor: 'gainsboro',
                trailWidth: 20,
                color: 'teal',
                strokeWidth: 20
            ).animate(val); 
         
    
<div class="content" v-for="fitness in fitness">
  <span> fitness </span>
  <div id="container"></div>
</div>

由于 id 仅与一个 div 相关联,因此我无法执行会创建另一个 div 的新 ProgressBar.Circle 对象。每次执行新的 ProgressBar.circle 时,有没有办法在 v-for 中动态创建一个具有不同 id 的新 div?有人可以帮我吗?

【问题讨论】:

您通常会创建一个包装 ProgressBar 的组件并呈现它。 【参考方案1】:

一种解决方案可以是为每个容器 div 提供唯一的 id,并为每个容器创建进度条。

试试下面的代码 -

import ProgressBar from 'progressbar.js'
var bar;

export default 
  data() 
    return 
      fitness: ['Dietary Intake', 'Exercise'],
      val: [0.65, 9]
    
  ,

  mounted() 
    this.showProgressBar();
  ,


  created: function() 

  ,

  methods: 
    showProgressBar: function() 
      this.fitness.forEach((f, i) => 
        new ProgressBar.Circle('#container-' + i, 
          trailColor: 'gainsboro',
          trailWidth: 20,
          color: 'teal',
          strokeWidth: 20
        ).animate(this.val[i]);
      );

    
  
<div class="content" v-for="(f, index) in fitness">
  <span> f </span>
  <div v-bind:id="`container-$index`"></div>
</div>

更新 - val 可以是一个数组。并且它的值可以从showProgressBar函数内部引用。

我假设 fitnessval 数组的长度相同。

更新 2 - 解释。

所以基本上这里有 2 个主要问题需要解决。

1。生成多个container div

我们需要生成多个container div,因为会有多个ProgressBars。但是我们需要区分它们,因此我们为它们中的每一个创建一个唯一的 id。这就是以下代码的作用。

<div class="content" v-for="(f, index) in fitness">
  <span> f </span>
  <div v-bind:id="`container-$index`"></div>
</div>

因为索引号是唯一的。将它们添加到“容器”会生成唯一 ID。见List Rendering

2。组件挂载时生成多个ProgressBars

这更简单,我们只需为每个“适合度”值创建新的ProgressBar

this.fitness.forEach((f, i) => 
  new ProgressBar.Circle('#container-' + i, 
    trailColor: 'gainsboro',
    trailWidth: 20,
    color: 'teal',
    strokeWidth: 20
  ).animate(this.val[i]);

参考 - Array forEach

【讨论】:

谢谢。但是,每次执行 div 时如何动态传递 val?就像我有 val : [0.65, 1.25, 9]。 你可以有一个 val 数组,你可以在 showProgressBar 中引用它们。 是的。完毕。另外,你能解释一下代码是如何工作的吗?我乐意去学。我对 Vue.js 很陌生 让我们continue this discussion in chat.【参考方案2】:

这是一个包装progressbar.js的可重用组件。

<template>
  <div class="container"><div ref="bar"></div></div>
</template>
<script>
  import ProgressBar from "progressbar.js"

  export default 
    props:["options", "val"],
    mounted()
      new ProgressBar.Circle(this.$refs.bar, this.options).animate(this.val)
     
  
</script>
<style>
  .container
    width:100px; 
    height: 100px
  
</style>

这是它在模板中的使用方式:

<div v-for="fit in fitness" class="fitness">
  <div>fit.name</div>
  <progress-bar :val="fit.val" :options="options"></progress-bar>
</div>

工作Example。

【讨论】:

@APJ 没问题 :) 可以进行一些改进。例如,监视对 val 的更改,以便进度可以动态更改。允许设置尺寸(以 px 为单位的大小)等。但这是一个不错的开始。 不过有一个小问题。我没有看到 div 之间的分隔或线 @apj 哪个 div?每次健身? 是的。每次健身之间 @APJ 这只是一个样式问题,与组件无关。我在示例中添加了 10px 的边距。你可以在 app.vue 的样式中看到它。

以上是关于如何在 Vue.js 中使用 v-for 动态创建新的 div?的主要内容,如果未能解决你的问题,请参考以下文章

在 vue js 中使用 v-for 在 div 内创建组件

vuejs中的v-for怎样动态增加循环数据

如何在 Vue.js 中使用 v-for 遍历对象数组?

如何在 vue.js 中同时使用 v-for 和源绑定?

如何在 Vue.js 中过滤数组和循环 V-for

Vue.js - 如何按特定属性对数组中的对象进行排序并使用“v-for”进行渲染