LoginSignup
1
1

More than 3 years have passed since last update.

条件付きレンダリング v-if で VeeValidate が機能しない

Last updated at Posted at 2019-10-05

DOM要素が保持される v-show を使用することで解決する。

v-if は 遅延描画 (lazy) です。 初期表示において false の場合、何もしません。条件付きブロックは、条件が最初に true になるまで描画されません。

一方で、v-show はとてもシンプルです。要素は初期条件に関わらず常に描画され、シンプルな CSS ベースの切り替えとして保存されます。

v-if

ラジオボタン切り替え後、数字以外の入力で VeeValidate が機能しない。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Sample</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
          integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
          crossorigin="anonymous">
</head>
<body>
<div class="container">
    <div id="app">
        <form>
            <div class="form-group">
                <div class="form-check form-check-inline">
                    <input type="radio" name="changeInput" value="1" id="radio1" class="form-check-input" v-model="changeInput" checked>
                    <label class="form-check-label">input1</label>
                </div>
                <div class="form-check form-check-inline">
                    <input type="radio" name="changeInput" value="2" id="radio2" class="form-check-input" v-model="changeInput">
                    <label class="form-check-label">input2</label>
                </div>
            </div>

            <div class="form-group" v-if="changeInput === '1'">
                <input type="text"
                       class="form-control"
                       name="input1"
                       v-model.number="value1"
                       v-validate="'numeric'"
                       :class="{'is-invalid': errors.has('input1')}">
                <div class="invalid-feedback" v-show="errors.has('input1')" >{{ errors.first('input1') }}</div>
            </div>

            <div class="form-group" v-if="changeInput === '2'">
                <input type="text"
                       class="form-control"
                       name="input2"
                       v-model.number="value2"
                       v-validate="'numeric'"
                       :class="{'is-invalid': errors.has('input2')}">
                <div class="invalid-feedback" v-show="errors.has('input2')" >{{ errors.first('input2') }}</div>
            </div>
        </form>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vee-validate@2.1.0-beta.9/dist/vee-validate.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vee-validate@2.1.0-beta.9/dist/locale/ja.js"></script>
<script>
    Vue.use(VeeValidate, {
        events: 'input',
    });
    new Vue({
        el: '#app',
        data: function () {
            return this.initialState()
        },
        created: function () {
            this.$validator.localize('ja');
        },
        methods: {
            initialState: function () {
                return {
                    value1: 0,
                    value2: 0,
                    changeInput: '1',
                }
            }
        }
    });
</script>
</body>
</html>

v-show

ラジオボタン切り替え後、数字以外の入力で VeeValidate が機能する。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Sample</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
          integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
          crossorigin="anonymous">
</head>
<body>
<div class="container">
    <div id="app">
        <form>
            <div class="form-group">
                <div class="form-check form-check-inline">
                    <input type="radio" name="changeInput" value="1" id="radio1" class="form-check-input" v-model="changeInput" checked>
                    <label class="form-check-label">input1</label>
                </div>
                <div class="form-check form-check-inline">
                    <input type="radio" name="changeInput" value="2" id="radio2" class="form-check-input" v-model="changeInput">
                    <label class="form-check-label">input2</label>
                </div>
            </div>

            <div class="form-group" v-show="changeInput === '1'">
                <input type="text"
                       class="form-control"
                       name="input1"
                       v-model.number="value1"
                       v-validate="'numeric'"
                       :class="{'is-invalid': errors.has('input1')}">
                <div class="invalid-feedback" v-show="errors.has('input1')" >{{ errors.first('input1') }}</div>
            </div>

            <div class="form-group" v-show="changeInput === '2'">
                <input type="text"
                       class="form-control"
                       name="input2"
                       v-model.number="value2"
                       v-validate="'numeric'"
                       :class="{'is-invalid': errors.has('input2')}">
                <div class="invalid-feedback" v-show="errors.has('input2')" >{{ errors.first('input2') }}</div>
            </div>
        </form>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vee-validate@2.1.0-beta.9/dist/vee-validate.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vee-validate@2.1.0-beta.9/dist/locale/ja.js"></script>
<script>
    Vue.use(VeeValidate, {
        events: 'input',
    });
    new Vue({
        el: '#app',
        data: function () {
            return this.initialState()
        },
        created: function () {
            this.$validator.localize('ja');
        },
        methods: {
            initialState: function () {
                return {
                    value1: 0,
                    value2: 0,
                    changeInput: '1',
                }
            }
        }
    });
</script>
</body>
</html>

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1