Vue.js+TypeScriptでもscopedなcssを書きたい
きっかけ
TypeScriptを勉強し始めたので、どうせなら今書いているVue.jsのアプリで使いたい。
時代はTypeScriptだ。イェッヘッヘ
と思って、やりだしたのですがコンポーネントのstyleをscopedな感じで書きたいときに大変困った。
素のVue.jsというか.vueファイルだとsytleタグにscopedを付与するだけで、localなスコープのcss定義になる。
<style scoped> .button-color{ color: red; } </style>
だけど、.tsファイルの場合どこに書けばよいんだ?
import Vue from 'vue'; import Component from 'vue-class-component'; @Component({ template: ` <button class="button-color">こんにちは!こんにちは!</button> `, }) export default class OtherComponent extends Vue { }
書くとこなくない?
というわけで、書き方を考えてみた。
別ファイルimport作戦
とりあえずcssファイルを別で作ってimportしていたが、これlocalじゃなくてglobalに全体へ適用されるみたいでつらい。
import Vue from 'vue'; import Component from 'vue-class-component'; import './HelloComponent.scss'; @Component({ template: ` <button class="button-color">こんにちは!こんにちは!</button> `, }) export default class HelloComponent extends Vue { }
もし、importしてlocalなスコープであれば、ほかのボタンに同じclassを指定してもスタイルが当たらないはず。
.button-color { color: red; margin: 5px; }
残念ながらcssファイルをインポートしてない、上のおはようボタンコンポーネントにもスタイルが当たってる。
css modulesを使おう
css moduleでは、localとglobalの定義を分けて書けるらしい。
そのcssファイルをtsの方で読み込むと、ちゃんとlocalなスコープになった。
classをバインドして、requireで読み込んだcssのクラス名を指定する。
scopedで定義していた時より、ちょっと面倒かな…
GitHub - css-modules/css-modules: Documentation about css-modules
import Vue from 'vue'; import Component from 'vue-class-component'; @Component({ template: ` <button :class="template.style['button-color']">こんにちは!こんにちは!</button> `, }) export default class HelloComponent extends Vue { private template = { style: require('./HelloComponent.scss'), }; }
localで囲んであげるとlocalスコープになる。
:local { .button-color { color: red; margin: 5px; } }
素敵。
css modulesだと、同じcssファイルにglobalな定義とlocalの定義を両方書けるので
.vueで書いていたscoped指定よりは、書き方が柔軟なのは良いことかなと思いました。
プロジェクトまるごとはこちら。
github.com