トップ/記事一覧
Vue.js で CSS 変数を使用する(Composition API サンプルコードあり)
📆2020/08/24🔖 NuxtJS
⚠ この記事は最終更新日から1年以上が経過しています。内容が古い箇所がある可能性があるためご注意ください。
Vue.js で CSS 変数を使う方法が分からなくて調べたのでそのメモです。ところどころ動作が分かってないところあったので、サンプルコードを書きながら検証してみました。
<template> 内で直接スタイルを当てるという方法もあるのですが、:after 疑似要素内で CSS 変数を使用したい場合はそうは行きません。(実際のプロジェクトでは、:after 疑似要素の background-image に props で受け取った値を使うコンポーネントを作りたかった)ということで、いろいろググりながら実現方法が分かったので、最小構成でサンプルコードを書いてみました。
サンプルコード
ボタンを押すたびにアプリケーション内の状態が切り替わり background の画像が切り替わるサンプルです。
JavaScript
<template> <!-- [2] styles を bind する --> <div class="container" :style="styles"> <div> <button @click="_onClickButton" class="button">ボタン</button> </div> </div> </template> <script lang="ts"> import { defineComponent, computed, reactive } from '@vue/composition-api' const urls = [ 'https://blog.35d.jp/img/glitched-01.png', 'https://blog.35d.jp/img/glitched-02.png', 'https://blog.35d.jp/img/glitched-03.png', ] type State = { index: number } export default defineComponent({ setup() { const state = reactive<State>({ index: 0 }) // [1] CSS 変数をキーバリューにした Object を作成 const styles = computed<Object>(() => ({ '--image-url': `url(${urls[state.index]})`, })) const _onClickButton = () => { state.index = (state.index + 1) % urls.length } return { _onClickButton, styles, state } }, }) </script> <style> .container { // [3] var(キー名) で CSS 変数として使用可能になる background-image: var(--image-url); } </style>
渡したいスタイルを詰め込んだオブジェクトを定義
JavaScript
// [1] CSS 変数をキーバリューにした Object を作成 const styles = computed<Object>(() => ({ '--image-url': `url(${urls[state.index]})`, }))
このように、オブジェクトを作成します。キーは、カスタムプロパティの命名規則に従い、ハイフン2個を付けるルールになっています(ハイフン2個じゃないと動きません)。今回の例では、background-image のプロパティ用のオブジェクトを作成しました。
styles を bind する
JavaScript
<!-- [2] styles を bind する --> <div class="container" :style="styles">
さきほど作成した styles オブジェクトを return することで、<template> 内で styles が見えるようになります。styles オブジェクトを、CSS を当てたい要素の :style に bind することで <style> 内でさきほど定義した CSS 変数として参照することができるようになります。
CSS 変数を使用する
JavaScript
<style> .container { // [3] var(キー名) で CSS 変数として使用可能になる background-image: var(--image-url); } </style>
bind した要素に付いているクラス内でしか、CSS 変数は使用できないので注意が必要です。
例によって、Nuxt.js でサンプルコードを書きました。GitHub でソースコード公開しています。2020/08/24 時点で、 Netlify にもデプロイしてあります(そのうち閉じる可能性もアリ)
▷ https://github.com/35d/vue-css-variables-sample
▷ https://festive-snyder-987a3d.netlify.app/
もっと良い書き方あったりしたら @___35d にこっそり教えて下さい。