LoginSignup
6
7

More than 1 year has passed since last update.

Nuxt3でimgタグのsrc属性に変数を使えない問題の回避策

Last updated at Posted at 2023-04-25

🤔 発生した問題

imgタグのsrc要素を静的に指定するとWebpackによりモジュールとして読み込まれる。
一方、src属性にv-bindを使い動的に指定するとそのままのパスとして扱われる。
この違いにより、何も考えずにsrcに変数を渡すと404エラーが発生してしまう。

<script setup>
    const fileName = 'img-1';
</script>

<template>
    <!-- 変数を展開せずにファイル名を指定すると表示される -->
    <img :src="~/assets/images/img-1.png" />

    <!-- 変数を展開しても画像ファイルが表示されない -->
    <img :src="`~/assets/images/${fileName}.png`" />
</template>

💡 解決法1

import.meta.globを使う。

<script setup lang="ts">
import { filename } from 'pathe/utils';

const glob = import.meta.glob('~/assets/images/*.png', { eager: true });
const images = Object.fromEntries(
  Object.entries(glob).map(([key, value]) => [filename(key), value.default])
);

const dynamic_image_name = 'img-1';
</script>

<template>
  <img :src="images[dynamic_image_name]" alt="Discover Nuxt 3" />
</template>

import.meta.globはVite.jsで提供されている関数みたいで、ファイルシステムからのモジュールのインポートをサポートしているらしい。
詳しくは参考リンクを参照のこと(参考)。

💡 解決法2

動的インポートimport()を使う。

<script setup lang="ts">
  const imageName = 'img-1'

  let image = {}
  try {
    image = await import(`~/assets/img/${imageName}.png`)
  } catch (e) {
    console.log(e)
  }
</script>

<template>
  <img :src="image.default" />
</template>

注意として、Vite内で使っているRollupの都合上、import()の引数が「変数で始まってはいけない」とか、「拡張子で終わらなければいけない」とか制約が色々ある。
詳しくは参考リンクを参照のこと(参考)。

Nuxt3で使えなかった解決法

require()を使う。

<script setup>
    const fileName = 'img-1';
</script>

<template>
    <!-- require()で囲ってあげる -->
    <img :src="require(`~/assets/images/${fileName}.png`)" />
</template>

これにより、モジュールとして読み込んでくれる。
だが、viteだとrequire()が使えないのでこの方法は採れなかった。

参考

Vue.jsで画像のsrcに変数を使ったら画像が表示されない - Qiita
【Vue.js】imgタグのsrc要素は指定の仕方によって読み込み方が違う - Qiita
require is not defined · Issue #12797 · nuxt/nuxt · GitHub
Assets with dynamic names are not resolved · Issue #14766 · nuxt/nuxt · GitHub
Nuxt - Starter (forked) - StackBlitz
plugins/packages/dynamic-import-vars at master · rollup/plugins · GitHub
Features | Vite (vitejs.dev)

6
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7