【Vue.js】フォームバリデーションで使うgetter/setter

# Tips1

[公式リファレンス](https://jp.vuejs.org/v2/guide/computed.html#%E7%AE%97%E5%87%BA-Setter-%E9%96%A2%E6%95%B0)

* 入力文字列が20文字以上だった場合にリアルタイムでerrorの表示をさせたい。
* 算出プロパティのget/setを使用して入力を監視する。

#### vue

```js

 <script>
        let app = new Vue({
            el:'#app',
            data(){
                return {
                    contact:{
                        yourName:'', //input要素を定義する。
                    },
                    hasError:{
                        nameError: false //error判定用の初期値
                    }
                }
            },
            computed:{
                yourName:{
                    get(){  //yourNameで入力された取得。
                        return this.contact.yourName
                    },
                    set(value){ //yourNameで入力された値を引数で受け取る。
                        if(value.length <= 20){
                            this.hasError.nameError = false //20文字以内だったらfalseをセット
                        } else {
                            this.hasError.nameError = true //20文字以上だったらtrueをセット
                        }
                        return this.contact.yourName = value //valueをyourNameに帰す
                    }
                }
            }
        })
    </script>
```

#### html

* CSS:20文字以上だった場合のerrorクラスにcssをあてる。
* 文字数カウント：20文字以上だった場合に、errorクラスを付与させる。
* v-show:20文字以上の時にメッセージを表示

```html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
    <title>Document</title>
    <style>
        .error{ //20文字以上だった場合のerrorクラスにcssをあてる。
            color:red;
        }
    </style>
</head>
<body>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.js"></script>
    <div id="app">
        <form>
            <label for="yourName">氏名</label>
            <input id="yourName" type="text" v-model="yourName"><br> <!-- computedで監視している値 -->
            <p :class="{error: hasError.nameError}">{{yourName.length}}/20</p> //20文字以上だった場合に、errorクラスを付与させる。
            <p v-show="hasError.nameError" class="error">氏名は20文字以内</p> //v-show:20文字以上の時にメッセージを表示
            {{contact.yourName}}
        </form>
    </div>

```


#### 全体

```vue
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
    <title>Document</title>
    <style>
        .error{
            color:red;
        }
    </style>
</head>
<body>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.js"></script>
    <div id="app">
        <form>
            <label for="yourName">氏名</label>
            <input id="yourName" type="text" v-model="yourName"><br> <!-- computedで監視している値 -->
            <p :class="{error: hasError.nameError}">{{yourName.length}}/20</p>
            <p v-show="hasError.nameError" class="error">氏名は20文字以内</p>
            {{contact.yourName}}
        </form>
    </div>

    <script>
        let app = new Vue({
            el:'#app',
            data(){
                return {
                    contact:{
                        yourName:'',
                    },
                    hasError:{
                        nameError: false //error判定用の初期値
                    }
                }
            },
            computed:{
                yourName:{
                    get(){
                        return this.contact.yourName
                    },
                    set(value){ //yourNameで入力された値を引数で受け取る。
                        if(value.length <= 20){
                            this.hasError.nameError = false
                        } else {
                            this.hasError.nameError = true
                        }
                        return this.contact.yourName = value //valueをyourNameに帰す
                    }
                }
            }
        })
    </script>
</body>
</html>
```