【翔んで】Vue + Vuetifyで確認ダイアログを作成してみた。【Vue.js】

## Vue流行ってますね

以前、[React + Material-UIで確認ダイアログを作成](https://qiita.com/pepaperon_p/items/4e1b25e1e0ebd54268fa)しまして、
せっかくなので、Vueも試してみることにしました。
初学者の方は、この両方を試してみるとReact/Vueをふんわりマスターできると
思います。Reactもhooksが無かったらヤバかったのではないかと思います。

![react.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533968/cc724ff3-a946-3f11-3da2-c362e83f737d.gif)

[■Vue & Vuetify CommonDialog](https://github.com/pepaperonp/vue-comm-modal)
![vuetify01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533968/919d2551-fbd3-e97f-5cd2-218e3e7adaa3.png)
![vuetify02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533968/64b71488-10ed-1971-f605-18f055df5a20.png)

**CodeSandbox**([https://codesandbox.io](https://codesandbox.io/))さんでデモも用意してきました。
[■DEMO](https://r2vqi.csb.app/)

##コード解説

**コンポーネント CommonDialog.vue**

```vue
<template>
  <v-row justify="center">
    <v-dialog v-model="dialog" persistent max-width="200">
      <v-card justify="center">
        <v-card-title class="headline"></v-card-title>
        <v-row style="width:100%">
          <v-col md="12" align="center">
            <div style="margin-left:15px">{{msg}}</div>
          </v-col>
        </v-row>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn color="green darken-1" text @click="no()">No</v-btn>
          <v-btn color="green darken-1" text @click="yes()">Yes</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </v-row>
</template>

<script>

  export default {
    props: ['msg','isOpen','doYes','doNo'],
    data () {
      return {
        dialog: false
      }
    },
    watch: {
      isOpen: function (val) {
        this.dialog = val
      }
    },
    methods: {
      yes () {
        this.doYes()
        this.dialog = false
      },
      no () {
        this.doNo()
        this.dialog = false
      }
    }
  }
</script>
```

**コンポーネント配置**

- :msg ... メッセージ
- :is-open ... 呼出し先の制御ステート
- :do-yes ... 「確認Yes」での実行処理
- :do-no ... 「確認No」でのクローズ処理

```vue
    <CommonDialog
            :msg="dlg.msg"
            :is-open="dlg.isOpen"
            :do-yes="dlg.doYes"
            :do-no="dlg.doNo"
    />
```
##用法

```vue
<template>
  <v-btn text @click="dlg.isOpen=true">do</v-btn>
</template>
<script>
    export default {
        data() {
          return {
            dlg: {
              msg: 'Message',
              isOpen: false,
              doYes: ()=>{
                ...
                this.dlg.isOpen=false
              },
              doNo: ()=>{
                this.dlg.isOpen=false
              }
            }
          }
        }
    }
</script>
```
##所感

Reactのコンポーネントとは正反対のアプローチですね。

Vueは敷居が低く簡単だ、といわれる所以はこのHTMLベタ書きテンプレートの
おかげだと思いますが、Reactもhooksの登場で、ほとんど難易度は変わらなくなりました。

Vueの特質すべき点は、そのHTMLとしての正統進化かもしれません。

WEBの歴史を見ると、まずHTMLがあり、CSSが現れ、JavaScriptが誕生しました。
Vueはこの３元素をコンポーネントの構成単位にしている訳です。
あくまでもHTMLがあり、そこへイベントを追加していく思想です。

Reactが革新的なのは逆にそのHTMLの柵を開放するため、ビューをJSXでカプセル化した
HTMLにした訳です。なのでビューの構成要素はJSXであって、HTMLではありません。
あのReactマークのクルクルしてる奴はJSXです。ReactはHTMLではないのです。
そういえば、XMLをHTMLにするXSLTというのがありましたが、その系譜なのかもしれません。

HTMLをコンポーネント化するという、この至極あたりまえの思想を実現するために
どれほどの屍が積み上がっていたか、package.jsonにその歴史が記されていますね。

ここで、それぞれの進化の果実を見てみましょう。
あるコンポーネントA、B、Cを条件により表示制御してみます。

####Vue
```vue
<h2 ...>
	埼玉県人にはそこらへんの草でも食わせておけ
	<A v-if="key === 'A'" />
	<B v-else-if="key === 'B'" />
	<C v-else-if="key === 'C'" />
</h2>

```
####React
```jsx
const tete = { A:<A/>, B:<B/>, C:<C/> }

<Typography ...>
    Reactか、それ以外か { tete['A'] }
</Typography>

```

![triforce02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533968/67f590e9-962a-8ef2-ea6c-c82efdf77379.png)