IT이야기

Vuelidate를 사용하는 상위 구성 요소의 하위 구성 요소에서 양식 입력 필드 검증

cyworld 2022. 5. 28. 10:14
반응형

Vuelidate를 사용하는 상위 구성 요소의 하위 구성 요소에서 양식 입력 필드 검증

나는 Vue Js와 Vuelidate를 처음 본다.다음과 같은 부모 컴포넌트에서 폼 입력 필드를 확인하려고 했습니다.https://github.com/monterail/vuelidate/issues/333

상위 구성 요소:

<contact-list ref="contactList" :contacts="contacts" @primaryChanged="setPrimary" @remove="removeContact" @ready="isReady => readyToSubmit = isReady"/>

자식의 메서드:

computed: {
    ready() {
        return !this.$v.email.$invalid;
    }
},
watch: {
    ready(val) {
        this.$emit('ready', val);
    }
},

methods: {
    touch() {
        this.$v.email.$touch();
    }
}

다음과 같이 부모로부터 touch() 메서드를 호출합니다.

submit() {
            this.$refs.contactList.touch();
        },

하지만 다음 오류가 발생합니다.

Error in event handler for "click": "TypeError: this.$refs.contactList.touch is not a function".

좋은 생각 있어요?고마워요.

나도 같은 문제에 직면해 있었다.내가 그것을 해결하기 위해 한 일은 이렇다.

  1. 글로벌 이벤트 풀을 만들었습니다.이벤트를 내보낼 수 있는 위치:$emit그리고 내 아이는 다음을 사용하여 구독할 수 있습니다.$on또는$once를 사용하여 구독을 해제합니다.$off내면에app.js아래 코드를 붙여넣습니다.다음은 이벤트 풀 액션 목록입니다.

    • 방출: 이거.$eventPool.$syslog()
    • 점등: 이거.$eventPool.$on()
    • 소등: 이거.$eventPool.$off()
    • 한 번: 이거.$eventPool.$1 회()

Vue.prototype.$eventPool = new Vue();

  1. 자 컴포넌트 내에, 나는 다음 컴포넌트를 작성했다.watch$v이하와 같습니다.폼의 상태를 부모 컴포넌트로 전송합니다.
watch: {
    "$v.$invalid": function() {
      this.$emit("returnStatusToParent", this.$v.$invalid);
    }
  }
  1. 이제 부모 컴포넌트 내부에서 다음과 같이 상태를 처리합니다.

<ChildComponent @returnStatusToParent="formStatus =>isChildReady=formStatus"></ChildComponent>

  1. 사용자에게 적절한 오류를 표시하기 위해$touch아이 양식그러기 위해서는 위에서 작성한 이벤트 풀에서 이벤트를 내보내야 하며, 우리 아이도 거기에 가입할 것입니다.

부모:

this.$eventPool.$emit("touchChildForm");

아이:

 mounted() {
    this.$eventPool.$on("touchChildForm", () => {
      this.$v.$touch();
      this.$emit("returnStatusToParent", this.$v.$invalid);
    });
  },
  destroyed() {
    this.$eventPool.$off("touchChildForm", () => `{});`
  }

도움이 되었으면 좋겠다:)

이 질문이 이미 받아들여진 해결책을 가지고 있는 후에 답변을 추가하지만, 다른 사람들에게 도움이 되기를 바랍니다.난 일주일 내내 이 일을 하고 있다.2레벨 깊이까지 중첩된 하위 컴포넌트가 있기 때문에 모든 검증을 트리거하고 폼이 유효한지 여부를 확인할 수 있는 최상위 상위 컴포넌트가 필요할 때 "ref" 접근법이 작동하지 않습니다.

결국 vuex를 꽤 간단한 메시지 모듈과 함께 사용했습니다.이 모듈은 다음과 같습니다.

const state = {
  displayMessages: [],
  validators: []
};

const getters = {
  getDisplayMessages: state => state.displayMessages,
  getValidators: state => state.validators
};

const actions = {};

const mutations = {
  addDisplayMessage: (state, message) => state.displayMessages.push(message),
  addValidator: (state, validator) => {
    var index = 0;
    while (index !== -1) {
      index = _.findIndex(state.validators, searchValidator => {
        return (
          searchValidator.name == validator.name &&
          searchValidator.id == validator.id
        );
      });
      if (index !== -1) {
        console.log(state.validators[index]);
        state.validators.splice(index, 1);
      }
    }

    state.validators.push(validator);
  }
};

export default {
  state,
  getters,
  actions,
  mutations
};

각 컴포넌트는 마운트된 이벤트에서 다음을 수행합니다.

  mounted() {
    this.addValidator( {name: "<name>", id: 'Home', validator: this.$v}) ;
  }

사용자가 홈페이지에서 "Submit(제출)" 버튼을 클릭하면 다음과 같은 모든 검증을 트리거할 수 있습니다.

  this.getValidators.forEach( (v) => {
    console.log(v);
    v.validator.$touch();
  });

vuelidate 객체의 $error, $invalid 속성을 쉽게 확인할 수 있습니다.테스트 결과 vuelidate 반응성은 그대로 유지되므로 개체가 vuex에 저장되더라도 구성 요소 필드의 변경 내용이 예상대로 반영됩니다.

GUI의 오류를 컴포넌트 자체에 전달하기 위한 메시지와 스타일링을 남길 예정이지만, 이 방법을 사용하면 오류가 발생했을 때 폼 제출을 일시 정지할 수 있습니다.

이게 좋은 일인가요?솔직히 전혀 모르겠어요.검증자를 추가하기 전에 제거해야 하는 유일한 hokey 비트입니다.검증 솔루션으로서의 문제라기보다는 컴포넌트 로직의 문제라고 생각합니다.

이 작업에 1주일이나 걸렸다는 것을 고려하면, 저는 이 솔루션에 매우 만족하지만, 어떤 피드백도 환영합니다.

부모 컴포넌트에서 폼을 제출하는 동안 자녀 컴포넌트의 유효성을 확인하려고 할 때 유사한 문제가 발생하였습니다.아이 컴포넌트의 깊이는 1레벨에 불과하기 때문에 이 방법으로 네스팅을 깊게 하면 동작하지 않거나 재귀적으로 확인해야 합니다.확인할 수 있는 더 좋은 방법이 있을 것 같은데, 저는 이게 효과가 있었어요.행운을 빌어요.

// parent component
  methods: {
    onSave() {
      let formIsInvalid = this.$children.some(comp => {
        if (comp.$v) { // make sure the child has a validations prop
          return comp.$v.$invalid
        }
      })

      if (!formIsInvalid) {          
        // submit data
      }          
      else {
        // handle invalid form
      }
   }

이 검증을 위한 다른 솔루션을 찾았습니다. 매우 간단합니다.상위 구성 요소:

<contact-list ref="customerContacts" :contacts="customer.contacts" />

하위 구성 요소의 유효성 검사:

:validator="$v.model.$each[index].name
...
validations: {
    model: {
        required,
        $each: {
            name: {
                required
            },
            email: {
                required,
                email
            },
            phone: {
                required
            }
        }

    }

}

부모에게 제출되는 경우:

async onSubmit() {
            if(this.$refs.customerContacts.valid())
...

언급URL : https://stackoverflow.com/questions/53628450/validate-form-input-fields-in-child-component-from-a-parent-component-with-vueli

반응형