【UI5】Vue.jsではじめるUI5 Web Components

##はじめに
UI5 Web Componentsを学んでみようと思ったきっかけは、SAP Communityに投稿された以下の[質問](https://answers.sap.com/questions/13129117/future-of-ui5-fiori.html)でした。

質問
>最近S/4のプロジェクトに参画しましたが、評価の結果Fioriはあきらめることにしました。理由は遅すぎるからです。GUIと比べるとユーザの生産性が30%も落ちます。
SAPは当初GUIをUI5に置き換えようとしていたと記憶していますが、進捗はあまりよくないようです。
UI5の将来はどうなるのでしょうか？UI5のプロダクトオーナーは顧客のユースケースを知っているのでしょうか。UI5はVueみたいに軽くなるのでしょうか？

回答1（抜粋）
>SAP FioriはSAP S/4HANAやその他で一貫したユーザー体験を提供するためのデザインコンセプトです。別の側面は、どのUI技術を使ってこの体験を実装するかということです。SAPUI5とUI5 Web Components（Angular, React, Vueの上で動く）はよい選択肢です。

回答2（抜粋）
>UI5の将来については、UI5をAngularJS, React and Vueで再利用できるwebcomponentsとして進化させるために多くの投資がすでに行われています。こちらをチェックしてみてください。https://sap.github.io/ui5-webcomponents/

興味深いのは、UI5のパフォーマンスが悪い件は否定せずに（※）「UI5 Web Componentsという選択肢もあるよ」と提示しているところです。私もUI5アプリを立ち上げたときに最初の描画までに時間がかかる印象は持っています。

では、代替案として提示されているUI5 Web Componentsとはどんなもので、どうやって使うのでしょうか？
この記事では、UI5 Web Componentsの概要紹介のあと、Vue.jsにUI5 Web Componentsを組み込んでみたいと思います。

※もちろんUI5自体のパフォーマンス向上のため、UI5ライブラリにも色々な改善が行われています。例えば、[レンダリング処理の改善](https://blogs.sap.com/2020/04/20/ui5ers-buzz-52-the-rendering-evolution-semantic-rendering-and-css-variables/)や[非同期に処理できる部分を増やす](https://blogs.sap.com/2020/02/06/ui5ers-buzz-47-performance-checklist-for-ui5-apps/)など。


##UI5 Web Componentsとは
Web Componentsとは、「WebページやWebアプリケーションの中で新たに、再利用可能でカプセル化された独自のHTMLタグを作成するためのWebプラットフォームのAPI」です。（[Web Componentsとは何か？](https://qiita.com/jtakiguchi/items/b1315f53b3726ff11b61)より引用）

UI5 Web ComponentsはWeb Componentsの考え方に基づき、[Fiori Design Guidelines](https://experience.sap.com/fiori-design-web/)に対応したUIエレメントを、フレームワークに関係なく使用することができるように開発されたものです。
たとえば以下のようなHTMLタグを書くだけで、FioriのDate Pikcerが配置できます。

`<ui5-date-picker></ui5-date-picker>`

フレームワークに依存しないので、Vue, Angular, Reactなどのフレームワークと一緒に使うことができます。

##UI5 Web Componentsの良いところ
SAPUI5と比較してUI5 Web Componentsには以下のような良い点があります。

①パフォーマンスが良い
去年のUI5Conで、SAPUI5とReactベースのUI5 Web Componentsを比較したセッションがありました。[Google Lighthouse](https://developers.google.com/web/tools/lighthouse)でパフォーマンスの評価を行ったところ、SAPUI5が**30**に対してUI5 Web Componentsは**95**と、かなりの差をつけていました。
https://youtu.be/5gUHpN_0uGY?list=PLVf0R17F93RXT2tzhHzAr-iiYTmc9KngS&t=620

②フレームワークに依存しない
UI5 Web ComponentsはVue, React, Angularなどの既存のフレームワークの中で使うことができるので、これらの技術をすでに知っている人にとっては学習コストが少なくて済みます。

##Fundamental Stylesとの違いは？
ここで思い出すのが、@monamonaさんが紹介されていた[Fundamental Styles](https://qiita.com/monamona/items/e5db3c3bd95ee9c81f73)です。Fundamental Stylesも、Vue, React, AngularのアプリをSAP Fiori風のUIにしてくれるのでした。UI5 Web ComponentsとFundamental Stylesは何が違うのでしょうか？

[こちら](https://github.com/SAP/ui5-webcomponents/issues/661)に私の聞きたいことが質問されていました。それによると、
>Fundamentalsはスタイルシートと、そのCSSを使ってHTMLがどのように見えるべきかについての推奨事項のセットです。HTMLを書くのと、ユーザの操作に応じてHTMLを更新するのはあなたのタスクです。
一方、UI5 Web Componentsはデザインだけでなく構造と機能も新しいHTML要素にカプセル化されているので、他のHTML要素と同じように内部的な動作を意識せずに使うことができます。
つまり、UI5 Web Componentsは完全に機能するUIコントロールであり、通常のHTMLタグと同じように使うことができます。Fundamentalsはデザインにフォーカスしており、必要に応じた機能の実装はあなたにゆだねられています。

つまり、

- Fundamental StylesはFioriらしい見た目にするためのスタイルシート
- Web Componentsは見た目と動作をカプセル化したHTML要素

ということのようです。


##Vue.jsとUI5 Web ComponentsでHello World
UI5 Web Componentsには、Angular, React, Vueの簡単なチュートリアルが用意されています。私はどれもやったことがなかったので、一番簡単と思われたVueではじめることにしました。Vueに関しては以下の動画を見ただけです。
https://www.vuemastery.com/courses/intro-to-vue-js/vue-instance/

ではさっそく、[Vueのチュートリアル](https://sap.github.io/ui5-webcomponents/playground/tutorials/vue/)に沿ってUI5のボタンをHTMLぺージに表示させてみましょう。

###1. Vue CLIをインストール
```
npm install -g @vue/cli
```

###2. プロジェクトの作成
```
vue create ui5-web-components-application
cd ui5-web-components-application
```
以下の構成のプロジェクトが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/a3faf36f-1392-33f9-580f-6a0bb645ce2b.png)

`npm run serve`を実行すると、ポート8080でアプリを表示することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/77667826-73cb-8982-9a6d-3ef2af74922e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/b2a6d2b5-cfd1-0ff8-fd65-bfe0fb2751ae.png)

###3. UI5 Web Componentsを追加する
```
npm install @ui5/webcomponents --save
```

###4. UI5 Web ComponentsをVue ignoredElementに追加する
**main.js**に以下のコードを追加します。

```
Vue.config.ignoredElements = [/^ui5-/];
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/8759507a-425d-8b8c-64cf-bdee442388fe.png)

###5. 使用するコンポーネントをインポートする
**App.vue**のscriptタグの中に以下を追加しました。

```
import "@ui5/webcomponents/dist/Button"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/c857ccf1-3b0d-16e4-5f09-eb6f04b2ebc8.png)

###6. アプリケーションでインポートした要素を使用する
**App.vue**に`<ui5-button >Hello world!</ui5-button>`を追加します。

```vuejs
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
    <ui5-button >Hello world!</ui5-button> 
  </div>
</template>
```
すると、UI5のボタンが追加されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/9bbd1b62-fbc8-5be6-3ddd-23cc2a449cbb.png)

###7. ボタンにアクションを追加する
このままだと押しても何も起こらないので、ボタンを押したときにダイアログが表示されるようにします。

7.1. ダイアログ用のコンポーネントをインポート

```
import "@ui5/webcomponents/dist/Dialog"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/5ba897c7-f3f0-c77e-5588-50423c59df81.png)

7.2. テンプレートにダイアログを追加

```vuejs
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>   
    <ui5-button >Hello world!</ui5-button> 
    <ui5-dialog id="hello-dialog" header-text="Welcome">
      <p>Hello!</p>
      <div slot="footer"	class="dialog-footer">
        <div style="flex: 1;"></div>
        <ui5-button id="closeDialogButton" design="Emphasized" @click="onClose">OK</ui5-button>
      </div>
    </ui5-dialog>      
  </div>
</template>
```

7.3. ボタンを押したときのアクションとダイアログを閉じるアクションを追加

```vuejs
<ui5-button @click="onButtonClick">Hello world!</ui5-button> 
```

```javascript

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  data() {
    return {
      dialog: null
    }
  },
  methods: {
    onButtonClick() {
      this.dialog = document.getElementById("hello-dialog")
      this.dialog.open()
    },
    onClose() {
      this.dialog.close()
    }  
  }
}
```

ボタンを押すとダイアログが開き、OKを押すと閉じます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/0c4dbe68-c666-7694-99bb-947996a99115.png)

##おわりに
以上、簡単でしたがVueでUI5 Web Componentsを使用してみました。HTML5とJavaScriptがわかれば比較的簡単に使えることがわかりました。
この先、ODataのバインディングや画面遷移をどうやるのか、オンプレS/4にデプロイできるのか、なども気になる点です。新しい発見があったらまた記事を書きます。

##参考
- [Web Componentsとは何か？](https://qiita.com/jtakiguchi/items/b1315f53b3726ff11b61)
- [UI5 Web Components](https://sap.github.io/ui5-webcomponents/)
- [UI5 Framework and UI5 Web Components](https://blogs.sap.com/2020/03/10/ui5-framework-and-ui5-web-components/)
- [Whats the difference between fundamental and ui5 webcomponents?](https://github.com/SAP/ui5-webcomponents/issues/661)