WebコンポーネントをVue.jsアプリと統合する
Webコンポーネントの仕様と実装はすべて成熟しているとは見なされないかもしれませんが、自分の目的に役立つと思われる興味深いコンポーネントやプロジェクトがまだたくさんあります。 そうは言っても、VueはプレーンなWebコンポーネントよりもはるかに多くの機能を提供しています。 (実際、Vueを使用して Webコンポーネントを作成することもできます。)では、両方の長所を活用してみませんか? VueでWebコンポーネントを使用するのは実際には本当に簡単です。 条件、プロパティ、さらにはイベントバインディングでさえ、期待どおりに機能し続けます。
準備
(このガイドは、vue-cliと webpack-simple
テンプレート。)
できるだけ少ないコードでプロパティとイベントを示す簡単なWebコンポーネントを作成してみましょう…
見よ:カチカチ音をたてる段落!基本的に、それは段落のラッパーです。 あなたはそのテキストコンテンツを content
属性。 ああ、それは tick
なんらかの理由で0.5秒ごとにイベントが発生します。 はい、私には創造性や実用的なものを思いつく能力がありません。 次に進みます。
<template id="x-ticking-paragraph">
<style>
p {
color: #42b983;
}
</style>
<p id="renderTarget">
</p>
</template>
<script>
const currentScript = document.currentScript;
customElements.define('x-ticking-paragraph', class extends HTMLElement {
static get observedAttributes() { return ['contents'] }
constructor() {
super();
let shadowRoot = this.attachShadow({mode: 'open'});
const template = currentScript.ownerDocument.querySelector('#x-ticking-paragraph');
const instance = template.content.cloneNode(true);
shadowRoot.appendChild(instance);
this.contents = '';
setInterval(() => {
this.dispatchEvent(new Event('tick'));
}, 500);
}
set contents(value) {
this._contents = value;
this.shadowRoot.getElementById('renderTarget').innerText = this._contents;
}
get contents() {
return this._contents;
}
attributeChangedCallback(name, oldValue, newValue) {
this[name] = newValue;
}
});
</script>
分かった分かった。 ここでは、古いHTMLインポートスタイルのコンポーネントを使用しています。これは、より文明化された時代に向けて、よりエレガントに感じられるためです。 また、まるでVueシングルファイルコンポーネントのように見えますね。 (Vueは、元のWebコンポーネントの仕様に一部影響を受けています。)
ここではすべてを説明するつもりはありません。むしろ、ModernTimes™用のより適切な Webコンポーネントを作成する方法を知りたい場合は、
了解しました。それでは、なんとかしてページにロードする必要があります。 また、途中でポリフィルを取得して、Chromeだけでなく多くのブラウザで機能するようにします。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Vue + Web Components</title>
<!-- Web Components Polyfill -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.13/webcomponents-lite.js"></script>
<!-- Loading our component -->
<link rel="import" href="./ticking-paragraph.html">
</head>
<body>
<div id="app"></div>
<script src="/dist/build.js"></script>
</body>
</html>
これですべてが完了したので、この段落の直後のタイトルで示されているように、最終的にVueでコンポーネントを使用できます。
Vueでのコンポーネントの使用
Vueをこのコンポーネントで動作させるために私たちがしなければならないのは、実際にはそれをホワイトリストに登録することだけです。 Vue.config.ignoredElements
. これは、要素/コンポーネントがVueが知らないソースからのものであることをVueに伝えるだけであり、コンパイラーが文句を言うのを防ぎます。
import Vue from 'vue';
import App from './App.vue';
Vue.config.ignoredElements = [
'x-ticking-paragraph'
]
new Vue({
el: '#app',
render: h => h(App)
});
今、他のコンポーネントと同じようにコンポーネントを使用してください! 反応性は損なわれません!
<template>
<div id="app">
<h1>Vue ❤ Web Components</h1>
<x-ticking-paragraph :contents="paragraphContents" @tick="logTick"></x-ticking-paragraph>
</div>
</template>
<script>
export default {
data() {
return {
paragraphContents: `I'm data from Vue rendering in a Web Component!`
}
},
methods: {
logTick() {
console.log(`The paragraph ticked again. >_>`)
}
}
}
</script>
最良の部分は、WebコンポーネントやVueアプリに変更を加える必要がないことです。これにより、どういうわけか、それらを不機嫌に連携させることができます。 それは箱から出してすぐに動作します! 実際、PolymerやReactなどの他のフレームワークを内部的に使用する要素を統合することもできます。
さて、これがあなたにとってどれほど役立つかは、あなたがVueと一緒にWebコンポーネントを使用しているかどうか(または使用したいかどうか)に完全に依存します。 とはいえ、他に何もないとしても、Webコンポーネントが未来である場合、Vueは将来にわたって利用できることを示しています。