環境
- Vue3
- Vite
- Vuetify3
- TypeScript
TL;DR
Vueプロジェクトのパスのエイリアス
例えばVueプロジェクトで、<img>
タグでsrc/assets
フォルダに配置した画像を表示したい場合、以下のようにファイルからの相対パスで記載することができます。
<img src="../assets/header_image.jpg">
ただしこの表記はファイルの位置によって..
の数を変えないといけないため面倒です。
そこでパスのエイリアスを利用すると便利です。プロジェクトを立ち上げると、ルートのsrcフォルダを示すエイリアス@
が設定されています。これにより以下のように記述することができ、ファイルの位置を気にせず同じ表記で画像を参照できます。
<img src="@/assets/header_image.jpg">
これはvite.config.ts
で定義されており、@
が./src
を示していることがわかります。
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
vue(),
],
resolve: {
// @をエイリアスとして設定している
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
Vuetifyのコンポーネント属性
VuetifyはVue.jsで使用できるUIフレームワークで、簡単な記述でマテリアルデザインのコンポーネントを作ることができます。(詳しくはVuetifyのリファレンスを参照ください)
Vuetifyコンポーネントには、画像を参照するコンポーネントがいくつかあります。例えば<v-img>
や<v-carousel-item>
です。これらはPropsで親コンポーネントからsrcを受け取り、画像を表示します。
<v-carousel>
<v-carousel-item
src="https://cdn.vuetifyjs.com/images/cards/docks.jpg"
cover
></v-carousel-item>
</v-carousel>
ここで、v-carousel-itemでassets
配下の画像を設定したいとします。しかし以下のように@
エイリアスを使用すると画像が表示できません。
<v-carousel>
<v-carousel-item
src="@/assets/header_image.jpg"
cover
></v-carousel-item>
</v-carousel>
Googleデベロッパーツールを使って、HTMLやコンソールのエラーを見ると
<img class="v-img__img v-img__img--cover" src="@/assets/home_1.jpg" style="display: none;">
GET http://localhost:5173/@/assets/home_1.jpg 404 (Not Found)
と表示されており、@
が.src
からのパスに変換できていないようです。
対応
これは、viteはsrcに指定しているパスの変換をコンパイル時に行いますが、変換対象のタグや属性がデフォルトで指定されているためです。
{
video: ['src', 'poster'],
source: ['src'],
img: ['src'],
image: ['xlink:href', 'href'],
use: ['xlink:href', 'href']
}
v-imgやv-carousel-itemといったタグは変換対象ではないので、コンパイル時に@
が変換されないようです。
そこで、vite.config.ts
を編集して変換対象のタグを追加します。template.transformAssetUrls
に対象のタグを記述します。
export default defineConfig({
plugins: [
vue({
//以下を追加
template: {
transformAssetUrls: {
tags: {
'v-img': ['src'],
'v-carousel-item': ['src'],
video: ["src", "poster"],
source: ["src"],
img: ["src"],
image: ["xlink:href", "href"],
use: ["xlink:href", "href"],
}
}
}
}
),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
こうすることで、Vuetifyコンポーネントでも@
を記述することができます。
<v-carousel>
<v-carousel-item
src="@/assets/header_image.jpg"
cover
></v-carousel-item>
</v-carousel>
おまけ
VuetifyコンポーネントのPropsのsrcに相対パスを記述することはできないようです。
@
を使わない場合、以下の記述で画像を表示できます。
1.ルートディレクトリからの絶対パスを書く
<v-carousel>
<v-carousel-item src="/src/assets/header_image.jpg" cover></v-carousel-item>
</v-carousel>
2.相対パスをimportしてから使う
<script setup lang="ts">
import header from '../assets/header_image.jpg'
</script>
~中略~
<v-carousel>
<v-carousel-item v-bind:src="header" cover></v-carousel-item>
</v-carousel>