Vue.jsのコンポーネントをWebComponents化してみる
きょうはVue.jsのコンポーネントをWebComponents化してみたよという話をば。
どうやって
WebComponents化しておけば、カスタム要素とJSをひとつ置けば、かんたんに任意のVue.js製コンポーネントを配置できるので便利そう~ということでお試ししてみました。
コンポーネント化には「vue-web-component-wrapper」をつかいます。 github.com
まずはインストールをば。
npm install --save-dev @vue/web-component-wrapper
あとは、コンポーネント化したいものを wrap
して、カスタム要素を登録すれば完了です。
import Vue from 'vue' import Player from 'src/player/player.vue' import wrap from '@vue/web-component-wrapper' const CustomElement = wrap(Vue, Player) window.customElements.define('map-player', CustomElement)
これで、HTMLを書いてゆけば、任意のVue.jsなコンポーネントを気軽に置くことができました。Props
もちゃんとカスタム要素の属性として記述できます。べんり。
<map-player mapid="1"></map-player> <!-- スクリプトはDOMが出来上がったら読まれるようにする --> <!-- ref: https://developer.mozilla.org/ja/docs/Web/Web_Components/Using_custom_elements --> <script src="/player.bundle.js"></script>
とおもいきや、なんだか思ったようにスタイルが当たらない...。これは、 vue-style-loader
が head
要素の中にビルドしたスタイルを差し込むためのようなので(WebComponents配下はShadow DOMでスタイルが分離される)、以下のようにloaderを設定し、WebComponentsのShadowDOM配下にスタイルタグが差し込まれるようにします。(Webpackでビルドされる前提)
/* webpack.config.js */ { // ... 省略... { test: /\.vue$/, loader: 'vue-loader', options: { shadowMode: true }, } { test: /\.css$/, use: [ { loader: 'vue-style-loader', options: { shadowMode: true } }, 'css-loader', ] } }
めでたしめでたし。
(ちなみに、「vue-web-component-wrapper」をつかわずに、 HTMLElement
を継承したクラスでVueインスタンスを作成し、window.customElements.define
する方法も試してみましたが、どうもスタイルをShadowDOMに入れ込む周りで苦戦して、とりあえずあきらめたのでした。)
なんのために
わたしのポートフォリオサイトをつくりたい(正確にはつくりなおしたい)と思い、せっかくなので「みんなでつくるダンジョン」のマップをポートフォリオサイトに埋め込みたいなと思ったのでした。そこで、Vue.js製マップ表示+たんけんコンポーネントをWebComponents化すれば、気軽にマップを張り付けられるじゃん~と思いついてやってみたのでした。
ではでは~。