概要
vue.jsでコンポーネントを作成した際に、cssで指定する背景画像を指定したいことってあると思うんですが、その方法についてハマったので共有します。
作ったもの
※ compostionAPIを使っていますが、必要に合わせてお使いのものにしてください。
<template>
<section :style="styles">
<h2>タイトル的な何か</h2> // ここで使う背景画像を動的に変更したいとする
</section>
</template>
<script lang="ts">
import { defineComponent, PropType, computed } from '@vue/composition-api'
type ContentType = 'hoge' | 'fuga'
const iconUrl: { [key in ContentType]: NodeRequire } = {
hoge: require('@/assets/images/hoge.png'),
fuga: require('@/assets/images/fuga.png')
}
type Props = {
contentType: ContentType
}
export default defineComponent({
name: 'custom-component',
props: {
contentType: {
type: String as PropType<ContentType>,
required: true
}
},
setup(props: Props) {
const styles = computed(() => {
return {
'--url': `url(${iconUrl[props.contentType]})`
}
})
return {
styles
}
}
})
</script>
<style lang="scss" scoped>
section {
h2 {
background: var(--url)
}
}
</style>
説明
- Vue.jsでCSSのカスタムプロパティを動的に追加するにはコンポーネントに
<:style="style">
でデータを渡して上げることで使えます。- こうすることで
root.element
の中にカスタムプロパティが登録されます。
- こうすることで
- 画像データのパスはそのまま渡しても、assetsのデータはバイナリで展開されるので、
require('画像パス')
で読み込んだ状態のものをurl()
に貼り付けた状態のものを渡して上げることでCSS内で動的に画像が変更されます。- ここが結構トラップなので注意
使う時
<custom-component contentType="hoge"/>
or
<custom-component contentType="fuga"/>
使うときは、contentType
に指定したtypeを指定してあげるだけです。
※ ここのtypeはunionで指定していますが、コンパイルエラーにはならないけど...
さいごに
画像が展開されたものになっていることを忘れていて、結構時間がかかってしまいました。
普段CSSをメインに触っていないので、 url()
がどんな動作をしているのかとか理解が少なかったのでなれないことをやると時間かかりますね。