如何在Vue.js中沟通/验证Component内部表单?

时间:2018-10-11 04:30:14

标签: vue.js vuejs2 vue-component vee-validate

我有一个包含姓名和地址成分的表格。在父母的页面上,我有一个提交按钮。我可以使用道具将数据从父母发送给孩子。 现在,我试图从父母的形式中获得孩子的价值观。我想从父母的形式验证孩子的领域。 如何做到这一点?

这是我的表单结构。

parent.vue

<form @submit.prevent="handleSubmit">
    <name-fields :user='user'></name-fields>
    <address-fields :address='address'></address-fields>

    <button>Register</button>
</form>

<script>
export default {
    data () {
        return {
            user: {
                firstName: 'Raja',
                lastName: 'Roja',
            },
            address: {
                doorNo: '11',
                state: 'KL',
                country: 'IN',
            },
            submitted: false
        }
    },
    components: {
        'name-fields': cNameFields,    
        'address-fields': cAddressFields,
    },
}
</script>

cNameFields.vue

<template>
  <div>
      <div class="form-group">
        <label for="firstName">First Name</label>
        <input type="text" v-model="user.firstName" v-validate="'required'" name="firstName" class="form-control" :class="{ 'is-invalid': submitted && errors.has('firstName') }" />
        <div v-if="submitted && errors.has('firstName')" class="invalid-feedback">{{ errors.first('firstName') }}</div>
    </div>
    <div class="form-group">
        <label for="lastName">Last Name</label>
        <input type="text" v-model="user.lastName" v-validate="'required'" name="lastName" class="form-control" :class="{ 'is-invalid': submitted && errors.has('lastName') }" />
        <div v-if="submitted && errors.has('lastName')" class="invalid-feedback">{{ errors.first('lastName') }}</div>
    </div> 
    </div>
</template>

<script>
export default {
  name: 'name',
  props: {
            user: Object,
            submitted : Boolean
        },
</script>

当前获得此输出: Currently getting this output:

我想做什么:

What I want to do:

2 个答案:

答案 0 :(得分:1)

使用它。$ emit https://vuejs.org/v2/api/#vm-emit 并使用手表https://vuejs.org/v2/api/#vm-watch

因此,在子组件中,您应该注意user.firstName和user.lastName的更改。调用手表中的emit并获取parent中的值。别忘了还发出vee-validate的this.errors包。

希望这会对您有所帮助:)

答案 1 :(得分:1)

您正在将对象作为道具传递给孩子,这些对象通过JavaScript中的引用传递。来自Vue docs ..

  

请注意,JavaScript中的对象和数组是通过引用传递的,因此,如果prop是数组或对象,则在子组件内更改对象或数组本身 会影响父状态。

这意味着您已经在父级中获取了子级的值,并且可以通过this.user.firstNamethis.user.lastNamethis.address.doorNo等在父级中访问它们。如果不是这样的话, t预期的行为,并且您希望隔离父母的数据,那么您应该调查deep cloning your objects

如果要将验证错误从子组件暴露给父组件,可以查看Scoped Slots。所以你可以做这样的事情..

parent.vue

<form @submit.prevent="handleSubmit">
    <name-fields :user='user'>
        <span slot="firstName" slot-scope="{validationErrors}" style="color:red">
            {{validationErrors.first('firstName')}}
        </span>
        <span slot="lastName" slot-scope="{validationErrors}" style="color:red">
            {{validationErrors.first('lastName')}}
        </span>
    </name-fields>

    <address-fields :address='address'>
        <span slot="doorNo" slot-scope="{validationErrors}" style="color:red">
            {{validationErrors.first('doorNo')}}
        </span>
        <span slot="state" slot-scope="{validationErrors}" style="color:red">
            {{validationErrors.first('state')}}
        </span>
        <span slot="country" slot-scope="{validationErrors}" style="color:red">
            {{validationErrors.first('country')}}
        </span>
    </address-fields>

    <button>Register</button>
</form>

cNameFields.vue

<template>
    <div>
        <div class="form-group">
            <label for="firstName">First Name</label>
            <input type="text" v-model="user.firstName" v-validate="'required'" name="firstName" class="form-control" :class="{ 'is-invalid': submitted && errors.has('firstName') }" />
            <slot name="firstName" :validationErrors="errors"></slot>
        </div>
        <div class="form-group">
            <label for="lastName">Last Name</label>
            <input type="text" v-model="user.lastName" v-validate="'required'" name="lastName" class="form-control" :class="{ 'is-invalid': submitted && errors.has('lastName') }" />
            <slot name="lastName" :validationErrors="errors"></slot>
        </div> 
    </div>
</template>

This is a great video解释了作用域插槽的工作原理。