Vue.jsでのボタン制御の方法

# はじめに
これはVue.jsに触り始めて間もない私が、自分で書いたコードを公式ドキュメントを参考に修正するといった内容になります。
そのため、私と同じようにVue.jsに触り始めた方の参考になれば幸いです。

# 具体的な内容
先日Vue.js+firebaseでSPAを作成したのですが、Vueを学び始めて数日だったので、**ボタン制御の部分**で誤った実装をしてしまっていました。
その時はこれでいいやで済ませたのですが、[公式ガイド](https://jp.vuejs.org/v2/guide/)を読んでいる際に正しい実装方法が載っていたので、これをもとにコードを修正しようと思います。

# 動作のイメージ
![動作イメージ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278934/271e3ac5-051b-093f-d261-c1881b1dfa9e.gif)

今回の対象は入力フォームに何も入力されていなかった場合にボタンが非活性になるという単純なものです。

# 元のコード
```vue:before.vue
<template>
  <div class="create">
    <div style="margin-right: 50px;text-align: right;">
      <header>NumG</header>
      <router-link to="/">Home</router-link>
    </div>
    <h1>Create</h1>
    <div>
      <p>
        <br />伝えたい言葉を入力してください。
        <br />※個人情報などは入力しないでください。
      </p>
    </div>
    <div>
      <form @submit="checkForm">
        <textarea cols="30" rows="5" :value="message" @input="doUpdate">いつもありがとう！
これからもよろしくね！</textarea>
      </form>
    </div>
    <div>
      <router-link
        id="confirmBtn"
        to="/Confirm"
        tag="button"
        class="btn btn-outline-primary"
      >Confirm</router-link>
    </div>
  </div>
</template>

<script>
export default {
  name: "Create",
  computed: {
    message() {
      return this.$store.getters.message;
    }
  },
  watch: {
    message: function() {
      let el = document.getElementById("confirmBtn");
      if (this.message.length) {
        el.removeAttribute("disabled", "disabled");
      } else {
        el.setAttribute("disabled", "disabled");
      }
    }
  },
  methods: {
    doUpdate(event) {
      this.$store.dispatch("doUpdate", event.target.value);
    },
    checkForm() {
      if (this.message) {
        return true;
      }
      this.error = null;
      if (!this.message) {
        this.error = "伝えたい言葉を入力してください";
      }
      event.preventDefault();
    }
  }
};
</script>
```

元のコードでは`router-link`(送信ボタン)に属性`disabled`をつけるために`watch`を使い、`message`(入力値)が変更になるたびに直接DOMの操作を行っていました。あまりVueっぽくない書き方だなぁと思いつつも他に書き方が分からず、時間もないためスルーしてしまいました。
ちなみにmethodsの`checkForm`は消し忘れた不要なコードです。。。
上記のwatchのおかげで入力値がない時はそもそもボタンが非活性となるため、ボタンが押せずイベントが発火しません。

# ドキュメントの該当箇所
ドキュメントの該当箇所は[テンプレート構文#属性](https://jp.vuejs.org/v2/guide/syntax.html#%E5%B1%9E%E6%80%A7)の部分です。

>>`<button v-bind:disabled="isButtonDisabled">Button</button>`

>`isButtonDisabled`が`null`、`undefined`、または`false`の値を持つ場合、`disabled`属性は描画された`<button>`要素に含められません。

つまり、`v-bind`を使えば`isButtonDisabled`の属性を自動で制御(付けたり外したり)できるということです。

# 修正したコード
```vue:before.vue
<template>
  <div class="create">
    <div style="margin-right: 50px;text-align: right;">
      <header>NumG</header>
      <router-link to="/">Home</router-link>
    </div>
    <h1>Create</h1>
    <div>
      <p>
        <br />伝えたい言葉を入力してください。
        <br />※個人情報などは入力しないでください。
      </p>
    </div>
    <div>
      <form>
        <textarea cols="30" rows="5" :value="message" @input="doUpdate"></textarea>
      </form>
    </div>
    <div>
      <router-link
        to="/Confirm"
        tag="button"
        class="btn btn-outline-primary"
        :disabled="isButtonDisabled"
      >Confirm</router-link>
    </div>
  </div>
</template>

<script>
export default {
  name: "Create",
  computed: {
    message() {
      return this.$store.getters.message;
    },
    isButtonDisabled() {
      return this.$store.getters.message.length <= 0;
    }
  },
  methods: {
    doUpdate(event) {
      this.$store.dispatch("doUpdate", event.target.value);
    }
  }
};
</script>
```

以下のように修正しました。
**①**`computed`にボタンの押下可否を判定するための算出プロパティ`isButtonDisabled()`を追加
　※入力値の文字数が0以下の場合にtrue(押下不可)を返すようになっています。
**②**`router-link`に`:disabled="isButtonDisabled"`を追加
　※念のため補足ですが`:`は`v-bind:`を省略した記法です。
**②**不要になった`watch`の削除
**④**その他の不要庵部分の削除(`form`の`@submit="checkForm"`、`textareaの無駄な例`、`router-link`の使わなくなった`id`、`methods`の`checkForm()`)

  
<br>
修正前と比較すると**`script`タグの中がかなりすっきりしたてVueっぽくなったと思います！**
特にDOMの要素を直接操作する処理が消えたのが大きいかなと思います。
※動作自体は修正前と変わらないので割愛します。

# まとめ
公式のドキュメントはちゃんと目を通した方がいいことが分かったので、時間を作って一通り目を通したいと思います。
もっといい書き方があればコメントいただければ幸いです。