用v-for动态渲染图像?

时间:2019-05-02 08:32:00

标签: vue.js

我想使用v-for从本地文件夹渲染图像,但是如何使其具有100%动态?

我尝试了this thread中提供的解决方案。当我尝试最有用的解决方案时,除非将图像名称填充到数组中,否则我只会得到空白页。

<template>
  <div class="comp__cardroster">
    <div class="container__cards"  >
      <div v-for="image in images" :key="image" class="tile--outer">
        <img class="tile--inner" :src="selectImage(image)" :alt="image"></div>
    </div>
  </div>
</template>

<script>

export default {
  data() {
    return {
      images: []
    }
  }
  methods: {
    selectImage(image) {
      return require('@/assets/card-images/' + image + ".jpg")
    }
  }
}
</script>

上面的代码给了我空白页。但是当我用值填充数组时,如下所示,我确实得到了结果。但我显然不希望如此。

data() {
    return {
      images: [1,2,3,4,5,6,7,8,9,10]
    }
  }

我希望代码能动态渲染图像,无论我的“ assets / card-images”文件夹中有多少图像,并且每次添加新图像时都不必手动在数组中添加值文件夹。

我在做什么错?我感谢您的任何建议。

更新

我尝试过的事情;

  • 将“图像”数组从数据移动到计算出的
  • 将“ selectImage”方法从方法移至计算
  • 将“ images”数组和“ selectImage”方法都移动到计算中

要么我得到空白页,要么得到与以前相同的结果

2 个答案:

答案 0 :(得分:0)

我认为自己的评论不够清楚,因此我将通过一个示例来解释我的意思;您应该可以毫不费力地将其应用于您的用例。我的src文件结构和结果的屏幕截图也在此答案的底部。


我制作的模板与您制作的模板基本相同(没有带有类的额外div):

<template>
  <div>
    <div v-for="image in images" :key="image">
      <img :src="selectImage(image)" :alt="image" />
    </div>
  </div>
</template>

这是我的剧本。我将在下面介绍所有内容:

<script>
  export default {
    name: 'app',
    computed: {
      images: function() {
        const x = require.context('@/assets/card-images/', true, /\.png$/)
        return this.importAll(x)
      }
    },
    methods: {
      importAll(r) {
        return r.keys().map(x =>
          x.substring(2, x.length) // remove "./" from file names
        )
      },
      selectImage(image) {
        return require('@/assets/card-images/' + image)
      }
    }
  }
</script>

计算

computed部分中,您可以定义动态生成或计算的值。由于您希望动态生成图像,因此我将images设为一个计算函数(可能只是一个值,您可以使用它)。

images所做的全部工作就是使用require.context来获取我的.png文件夹中所有@/assets/card-images/图像的列表,并从中修剪前几个字符他们。

方法

importAll仅检索并修剪图像名称。我这样做是因为,否则,它们会认为图像位于@/assets/card-images/./xxxxx.png处-可能有更好的方法,但是效果很好。

selectImage从您传入的文件名中获取图像(如果存在)。如果图像名称不存在,则会中断,但实现方式不应该发生这种情况。


注意:从技术上讲,如果您确实愿意,可以通过将v-for循环直接放在img标签上来缩短v-for循环,尽管我认为这不太可读:

<template>
  <div>
    <img v-for="image in images"
         :key="image"
         :src="selectImage(image)"
         :alt="image" />
  </div>
</template>

这是我的src文件夹结构。只要图像具有与您在script标记中使用的扩展名相同的扩展名,这些图像就无关紧要了:

folder structure

这是代码输出的内容(所有图像只是Vue徽标的副本):

output


编辑

如果要保留初始的images数组,可以将computed的内容移至生命周期方法mountedcreated中(取决于您的用例) 。阅读有关生命周期方法herehere的更多信息。这是我的组件在mounted中的计算结果:

<template>
  <div>
    <div v-for="image in images" :key="image">
      <img :src="selectImage(image)" :alt="image" />
    </div>
  </div>
</template>

<script>
  export default {
    name: 'app',
    data() {
      return {
        images: []
      }
    },
    mounted() {
      const x = require.context('@/assets/card-images/', true, /\.png$/)
      this.images = this.importAll(x)
    },
    methods: {
      importAll(r) {
        return r.keys().map(x =>
          x.substring(2, x.length) // remove "./" from file names
        )
      },
      selectImage(image) {
        return require('@/assets/card-images/' + image)
      }
    }
  }
</script>

答案 1 :(得分:-1)