使用 v-for 动态渲染图像?

Dynamic rendering of images with v-for?

我想使用 v-for 渲染本地文件夹中的图像,但如何使其 100% 动态化?

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

<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" 文件夹中有多少图像,并且每次添加新图像时都不必手动在数组中添加值文件夹。

我做错了什么?谢谢你的建议。

更新

我尝试过的东西;

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

使用 requireAll 方法获取数组和您的计数。或者 custom loader.

node.js require all files in a folder?

我觉得我的评论不够清楚,所以我会用一个例子来解释我的意思;您应该能够以最小的努力将其应用于您的用例。我的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 获取我的 @/assets/card-images/ 文件夹中所有 .png 图像的列表,并修剪前几张他们的角色。

方法

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

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


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

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

这是我的 src 文件夹结构。图片叫什么并不重要,只要它们的扩展名与您在脚本标签中使用的扩展名相同即可:

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


编辑

如果你想保留初始的 images 数组,你可以将 computed 的东西移到生命周期方法 mountedcreated 中(取决于你的用途-案件)。阅读有关生命周期方法的更多信息 here or here。这是我的组件在 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>