🖼️
【Vue3,Nuxt3】Bodyのbackground-imageの画像を動的に変えたい時はuseHeadを使おう
<body>
で背景画像を指定していて,それを動的に切り替えたい場合,Vue3/Nuxt3ならばuseHeadを使うのが良さそうです。
インストール方法
Vue3の場合
npm install unhead
Nuxt3の場合
同梱なので最初から使えます。
使用例
<script setup>
const userImage = ref(/hogehoge.png)
useHead({
bodyAttrs: {
style: computed(() => {
if (userImage.value) {
return "background-image: url('" + userImage.value + "')" //()内は形式に合わせて変更してください
}
})
}
})
</script>
bodyAttrs
のstyle
を変更すると,HTMLの出力としては<body style=hogehoge>
となります。
computed
を用いることで,動的に値を計算して出力するようにします。
classを変更すると失敗する
Tailwindcssを使っていると,styleよりもclassを先に使おうという考えになるので,
<script setup>
const userImage = ref(/hogehoge.png)
useHead({
bodyAttrs: {
class: computed(() => {
if (userImage.value) {
return `bg-[url('${userImage.value}')]`
}
})
}
})
</script>
このように書くことになりますが,これだとブラウザコンソール上で<body>
のclassが切り替わっているのは確認出来るものの,画像が出力されません。
なぜ失敗するかの考察
おそらくbodyが出力されるタイミングで,styleが適用されてないからだと思います。某TCGで言うならばタイミングを逃すと同じ概念です。
-
styleを切り替えた場合
<body>
を生成しようとする→styleを適用する→<body>
が生成される -
classを切り替えた場合
<body>
を生成しようとする→styleを適用する→<body>
が生成される→cssファイルが読みこまれる→対応するclassにstyleを適用する
bodyは一般的なコンポーネントとは異なり最初に生成されるため,直接styleで記述してあげないと画像パスにアクセスするタイミングを逃してしまい,画像が取得されないという結論になりました。間違っていたらごめんなさい。
あとがき
- とりあえずuseHead()でbodyAttrsのstyleを変更すれば動く
- 背景画像を動的に変更するのに取り組んだところ,ライフサイクルの概念や,renderについて学ぶいいきっかけになった
- 解決に3時間くらいかかったので,これを見て将来の自分や他の人の時短になれば幸い
Discussion