2018年5月25日 星期五

[Vue] vue-form - Get form state from component


  Vue.js    vue-form     validator


Introduction


vue-form is for form validation for Vue.js 2.2+.
Here is a tip for how to get form-state from component to enable/disable a button in parent (Vue instance).





Environment


vue.js 2.5.13
bootstrap 4.0.0
vue-form 4.7.1



Implement


The concept is store form-state in both parent and sub-component.

Parent

JS

var app = new Vue({
    el: '#app',
    data: {
        formstate: null;
},
}


HTML

<user-info @update-state="function(val){ formstate=val; }"
 ></user-info>
<input type="button" value="Save" :disabled="formstate.$invalid" class="form-control" />

We will create user-info component later, now in html we shall provide an event: update-state, as an emit callback for component: user-info.



Component

We need to watch the form-state and emit the parent event in order to update the one in parent.

Vue.use(VueForm);

Vue.component('user-info', {
    data: function () {
        return {
            formstate: {},
            user: {
                name: "",
                nickname:""
            }
        }
    },
    watch: {
        formstate: function (newVal, oldVal) {
            var vm = this;
            this.$emit('update-state', this.formstate);

        }
    },
    template: `<vue-form :state="formstate">
                <div class="form-group required">
                    <label class="control-label col-md-4">Name</label>
                    <validate class="col-md-8 text-left">
                        <input type="text" v-model="user.name" name="userName" required />
                    </validate>
                </div>
              <div class="form-group required">
                    <label class="control-label col-md-4">Nickname</label>
                    <validate class="col-md-8 text-left">
                        <input type="text" v-model="user.nickname" name="userNickname" required />
                    </validate>
                </div>
            </vue-form>`
});



Result





Quick way by using .sync Modifier

.sync Modifier is new on Vue.js 2.3.0+
We can refactor our codes in a cleaner way like this,

Parent: Modify HTML

<user-info :state.sync="formstate"></user-info>
<input type="button" value="Save" :disabled="formstate.$invalid" class="form-control" />


In :state.sync="formstate"

state: the prop of component
.sync: .sync Modifier
formstate: the prop of parent


It is the shorthand(sugar) for the following pattern:

<user-info :state="formstate" v-on:update:title="formstate = $event"></user-info>



Component

Since we know how .sync Modifier works.
We then update the emit-event name in component.

Vue.use(VueForm);

Vue.component('user-info', {

    props: ['state'],
    watch: {
        formstate: function (newVal, oldVal) {
            var vm = this;
            this.$emit('update:state', this.formstate);
        }
    },
    data: skip…
    template: `skip…`
`
});


Which will result in the same effect for enable/disable the parent’s submit button.



Reference





沒有留言:

張貼留言