先日個人的にVue.jsで開発してた時に、Vue.jsのbackground-image
指定でハマって推定1day溶かしてしまったので、
悲しい思い出とともに、Vue.jsでの画像指定方法(imgタグとbackground-imageでの指定)を振り返ります
※ ハマった件に関しては後日30分で解決しました。
TL;DR
- 画像って
./static
と./assets
どっちに置くの? -
./assets
に置いた画像の振る舞いが、思ってんのと違った
とりあえずcodesandoboxにサンプル作ったので、読書辛い人はこっちだけで十分そう。
はじめに
通常の画像指定方法
いちおう一般的な画像表示だとだいたい以下の方法が考えられますね
imgタグを使用
<img src="./images/image.png" />
css background-imageで指定
<!--
1. 別ファイルもしくはstyleタグからstyle当てる
-->
<style>
.bg{
background-image: url("./images/image.png")
}
</style>
<div class="bg" />
<!--
2. style属性を追加しインラインでstyle当てる
-->
<div style="background-image: url('./images/image.png');" />
canvasでctx.drawImage(image, dx, dy)
する
※ 今回は考慮しないので省略
ここから本題
通常の指定方法に加えて、Vue.jsではimageのpathが固定でない場合(apiで取得や、propsで渡されるなど)があるので、ちょい増えます
あとcanvasに関しては、今回めんどいので説明省きます
Vue.jsでの画像指定考慮する点
Vue.jsで画像指定する時に考慮するポイントはとりあえずこんな感じでしょう
- html要因
- imgタグを使用する
- css の
background-image
で指定する- classなどでstyle当てる
- div要素などにstyle属性を追加しインラインでstyle当てる
- 画像の置き場所
-
./assets
ディレクトリ -
./static
ディレクトリ - プロジェクト外: 外部URLのものを使用(APIで画像取得したりする場合)
-
- pathの 変数 or 定数
- 定数: いつも通り。楽チン
- 変数: レンダリング時やイベント時にpathが決定する。(styleタグ内では使用できないみたい)
なかなか多いぞ?
単純計算で 3 * 3 * 2 = 18
。 18通り。
ただ一部組み合わせ的にできないものもあるので、少し減りますね。
考慮しないケース
styleタグ内にvueの変数使用できないみたいなので、 styleタグ x 変数path
のケースは考慮しません。
あと、一旦プロジェクト外の画像を使用するケースは保留しときます。
Vue.jsでの画像指定方法
前項の考慮する点から、サンプルを作っていきます。
画像の置き場所をベースに、上記考慮点を元にしてパターンを作っていきます。
- 画像の置き場所
./assets
に画像配置./static
に画像配置
- 考慮点
- 1-1. imgタグに指定。
- 1-2. imgタグに指定。変数使用
-
- css classで
background-image
指定
- css classで
- 3-2. css inlineStyleで
background-image
指定 - 3-1. css inlineStyleで
background-image
指定。変数使用
(表示されないパターンもどんどん書いていきます。)
codesandoboxにサンプル上げてるんで、こちらでみて欲しい...
以下しばらく、codesandoboxのサンプルの繰り返しなるので、飛ばしても良いです。
一応変数として使用する画像はscript部分にこんな感じで書いておきます
<script>
import AssetsImage from "@/assets/img-assets.png";
// import AssetsImage from "../assets/img-assets.png"; // ← こっち記述でも良い!
export default {
data() {
return {
assetsImage: AssetsImage,
assetsImage_NG: "../assets/img-assets.png",
staticImage: "/img-static.png"
};
}
};
</script>
./assets
に画像配置
# assets-1-1: imgタグに指定。
<img class="img" src="../assets/img-assets.png" width="100" />
<!--
- 表示される。(普通慣れ親しんだ書き方....
-->
# assets-1-2: imgタグに指定。変数使用
<img class="img" :src="assetsImage" width="100" />
<!-- こっちはダメでした↓ -->
<img class="img" :src="assetsImage_NG" width="100" />
<!--
- 変数でpathっていうか画像データ渡してる...のですね
- ちなみに変数にassets配下のパス突っ込む場合は表示されない。
-->
# assets-2: css classで background-image指定
<div class="bg bg-assets"></div>
<style>
.bg-assets {
background-image: url("../assets/img-assets.png");
}
</style>
<!--
- まあ表示されない
-->
# assets-3-1: css inlineStyleで background-image指定
<div
class="bg"
:style="{ 'background-image': 'url(../assets/img-assets.png)' }"
/>
<!--
- 出ない。(上の流れから出ないのはわかっていたよ...
- これで、いけると思って1日溶かした...
-->
# assets-3-2: css inlineStyleで background-image指定。変数使用
<div
class="bg"
:style="{ 'background-image': 'url(' + assetsImage + ')' }"
/>
<!-- こっちはダメでした↓ -->
<div
class="bg"
:style="{ 'background-image': 'url(' + assetsImage_NG + ')' }"
/>
<!--
- assetsImage は表示される!
-->
./static
に画像配置
# static-1-1: imgタグに指定。
<img class="img" src="/img-static.png" width="100" />
<!--
- 当たり前のように表示される
- static配下のファイルはプロジェクト配下に移動されるみたいですね。
-->
# static-1-2: imgタグに指定。変数使用
<img class="img" :src="imgStatic" width="100" />
<!--
- 表示される。
-->
# static-2: css classで background-image指定
<div class="bg bg-static"></div>
<style>
.bg-static {
background-image: url("/img-static.png");
}
</style>
<!--
- 問題なく表示!
-->
# static-3-2: css inlineStyleで background-image指定
<div
class="bg"
:style="{ 'background-image': 'url(/img-static.png)' }"
/>
<!--
- こちらも全然出るぜ!
-->
# static-3-1: css inlineStyleで background-image指定。変数使用
<div
class="bg"
:style="{ 'background-image': 'url('+staticImage+')' }"
/>
<!--
- 表示される。
- `./static`でやったやつ全部表示されちゃった
-->
振り返り
というわけで、./assets
と./static
配下に置いた画像ではだいぶ書き方が違うのだなってことがわかりました。
./assets
配下の画像
./assets
に置いている画像ファイルは画像ファイルとして参照してるのではなく、
base64にエンコードされて、src="hoge"やurl="hoge"のところに出力してるみたいです。(参考:アセット URL ハンドリング · vue-loader)
つまり、キャッシュとかは見込めないですね...
./static
配下の画像
逆に./static
に置いてる画像ファイルは、プロジェクトルートに持ってってくれるので、
/{fileName}
で簡単に呼べますね。
キャッシュも効きますね。
要は、./assets
ファイルの扱いがイレギュラーだったということなので、外部のURLの場合も./static
配下に置いてる画像と同じような扱いでいけると思います。!
あれ? ./assets
に画像を置くタイミングはいつになるのだ...? 教えて詳しい人
最後に
ちなみに、assetsに置いたimageをbackground指定しようとして1日溶かしました!
まあ、全ての元凶は
staticフォルダがあることに気がつかなかったこと と
vue-cli
のhelloWorldでassets配下の画像を使用している罠 のためでした。
そりゃあ、少し考えれば、少しドキュメント見ればわかるけど、
何も考えていなかったためまんまと「画像はassets内ね!おk!」となります。罠にハマりました。
それでは良いVue lifeを!