Home > Net >  how to validate child form from parent component in Vue
how to validate child form from parent component in Vue

Time:09-15

I have a child component which includes form:

<el-form :model="abc" ref="ruleForm" :rules="rules">
      <el-form-item prop="files">
        <abc-card :title="getTranslation('abc.files')">
          <file-selector v-model="abc.files" />
        </abc-card>
      </el-form-item>
</el-form>

And I want to add simple validations to this form:

rules: function () {
      return {
        files: [
          {
            type: 'object',
            required: true,
            trigger: 'change',
            message: 'Field required',
          },
        ],
      };
    },

But my click button is in the parent component:

<files v-model="editableAbc" ref="editableTab" />
<el-button type="primary" @click="submitForm()">Create</el-button>

methods: {
submitForm() {
        this.$refs.form.validate((isValid) => {
    if (!isValid) {
      return;
    }
    ////API CALLS////
  });
      },
    }

So I am trying to achieve that when the button is clicked the navigation should be rendered. How can I do that?

CodePudding user response:

The "files" component is the form you're talking about? If so, then ref should be placed exactly when calling the 'files' component, and not inside it. This will allow you to access the component in your parent element.

<files v-model="editableAbc" ref="ruleForm" />

There is a method with the props, which was mentioned in the comments above. I really don't like it, but I can tell you about it. You need to set a value in the data of the parent component. Next you have to pass it as props to the child component. When you click the button, you must change the value of this key (for example 1). In the child component, you need to monitor the change in the props value via watch and call your validation function.

// Parent
<template>
  <div >
    <ChildComponent />
  </div>
</template>

<script>
export default {
  data() {
    return {
      updateCount: 0,
    };
  },

  methods: {
    submitForm() {
      // yout submit method
      this.updateCount  = 1;
    },
  },
};
</script>

// Child

<script>
export default {
  props: {
    updateCount: {
      type: Number,
      default: 0,
    },
  },
  watch: {
    updateCount: {
      handler() {
        this.validate();
      },
    },
  },
  methods: {
    validate() {
      // yout validation method
    },
  },
};
</script>

And one more solution. It is suitable if you cannot place the button in the child component, but you can pass it through the slot. You need to pass the validate function in the child component through the prop inside the slot. In this case, in the parent component, you will be able to get this function through the v-slot and bind it to your button.

// Parent 
<template>
  <div >
    <ChildComponent>
      <template #button="{ validate }">
        <button @click="submitForm(validate)">My button</button>
      </template>
    </ChildComponent>
  </div>
</template>

<script>
import ChildComponent from "./ChildComponent";

export default {
  components: {
    ChildComponent,
  },

  methods: {
    submitForm(cb) {
      const isValid = cb();
      // your submit code
    },
  },
};
</script>

// Child

<template>
  <div >
    <!-- your form -->

    <slot name="button" :validate="validate" />
  </div>
</template>

<script>
export default {
  methods: {
    validate() {
      // yout validation method
      console.log("validate");
    },
  },
};
</script>

CodePudding user response:

As per your requirement, My suggestion would be to use a ref on child component to access its methods and then on submit click in parent component, trigger the child component method.

In parent component template :

<parent-component>                                                                                                                                                        
      <child-component ref="childComponentRef" />
      <button @click="submitFromParent">Submit</button>                                                                      
</parent-component>

In parent component script :

methods: {
  submitFromParent() {
    this.$refs.childComponentRef.submitForm();
  }
}

In child component script :

methods: {
  submitForm() {
    // Perform validations and do make API calls based on validation passed.
    // If you want to pass success or failure in parent then you can do that by using $emit from here.
  }
}
  • Related