IT이야기

Vue2의 조건부 소품

cyworld 2022. 7. 4. 22:50
반응형

Vue2의 조건부 소품

수.props아이 컴포넌트에 대한 소품으로요.

처음에는 컴포넌트 안에 폼과 테이블이 들어있었습니다.이 형식은 입력을 받고 비동기 요청이 수행되며 사용자가 선택할 수 있도록 테이블이 렌더링됩니다.사용자는 버튼을 눌러 테이블을 숨기고 폼을 다시 불러와 파라미터를 다시 입력할 수 있습니다.폼의 내용은 부모 상태에 따라 달라지므로 마지막 검색 매개 변수는 여전히 폼에 남아 있습니다.

이 문제는 부모 컴포넌트의 폼과 테이블을 모두 서브 컴포넌트로 만들기 위해 컴포넌트를 리팩터 했을 때 발생했습니다. 이 폼은 ★★★★★★★★★★★★★★★★★★★★★★」$emit를 부모에게 합니다.props테이블로 이동합니다.이것은 정상적으로 동작했지만, 유저가 「폼으로 돌아가기」버튼을 누르면, 폼이 재렌더 되어, 그 상태가 초기치로 리셋 됩니다.

서식의 요.props하지만 그 때문에 처음에 값을 설정하는 데 문제가 생겼습니다.소품들을 직접 변형시키고 싶지 않았기 때문에, 다음과 같은 방법을 시도했습니다.

폼 컨테이너표시하다

<template>
  <div v-if="formShown">
    <form-component :initialValues="formValues" @formSubmitted="displayResults"></form-component>
  </div>
  <div v-if="tableShown">
    <table-component :results="fetchedResults" @returnToForm="returnToForm"></table-component>
  </div>
</template>
<script>
  export default {
    data(){
      return{
        formShown: true,
        tableShown: false,
        formValues:{
          address1: '',
          address2: '',
          address3: '',
          country: ''
        },
        fetchedResults: []
      }
    },
    methods:{
     async displayResults(){
        this.fetchedResults = await someAsynchronousCall();
        this.formShown = false;
        this.tableShown = true;
     },
     returnToForm(){
       this.tableShown = false;
       this.formShown = true;
     }
    }
  }
</script>

폼 컴포넌트표시하다

<template>
  <!--Some form fields here, bound to data(){}, ommitted for brevity-->
</template>
<script>
  export default{
    props:['initialValues'],
    data(){
      return{
        //Original structure
        /*selectedAddress:{
          address1: '',
          address2: '',
          address3: '',
          country: ''
        }*/
        selectedAddress: JSON.parse(JSON.stringify(this.initialValues)) //Object.assign({}, this.initialValues) //tried both of these for deep copy
      }
    }
  }
</script>

되었을 때 빈 오브젝트 빈만을 가진 즉, 이 「빈 속성」으로 되고 있는 것을 의미합니다.undefined

그런 다음 3진수를 사용하여 다음과 같이 소품이나 빈 문자열의 값을 사용하여 데이터 개체를 초기화했습니다.

data(){
  return{
    selectedAddress: {
      address1: this.initialValues.address1 ? this.initialValues.address1 :'',
      address2: this.initialValues.address2 ? this.initialValues.address2 :'',
      address3: this.initialValues.address3 ? this.initialValues.address3 :'',
      country:this.initialValues.country ? this.initialValues.country :''
    }

  }
},

하면 '가 발생해요.selectedAddress인스턴스(instance)에 정의되어 있지 않지만 렌더링 중에 참조됩니다.소품을 초기화하기 위해 삼진법을 사용하는 것은 잘못된 것이라고 생각합니다.

그리고 나서 소품들을 확인해보려고 했는데mounted(){}라이프 사이클을 사용하여 다음과 같이 데이터 속성을 설정합니다.

mounted(){
      if(!this.initialValues || _.isEmpty(this.initialValues)){
        Logger.info(`no props passed, no setup needed`);
        return;
      }
      if(this.initalValues.address1){
        Logger.info(`setting address 1`);
        this.selectedAddress.address1 = this.initalValues.address1;
      }
      if(this.initialValues.address2){
        Logger.info(`setting address 2`);
        this.selectedAddress.address2 = this.initalValues.address2;
      }
      if(this.initialValues.address3){
        Logger.info(`setting address 3`);
        this.selectedAddress.address3 = this.initalValues.address2;
      }
      if(this.initialValues.country){
        Logger.info(`setting country`);
        this.selectedAddress.country = this.initalValues.country;
      }
    }

폼의 첫만, 「 」는 「 」를 참조해당」의 「해당」의 「해당」의 「해당」의 「해당」을 참조해 주세요.this.initialValues 있다undefined이치노 했더니 ★★★★★★★★★★★★★★★★.initialValues '', '존재하지 않는다', '존재하지 않는다', '존재하지 않는다',mounted라이프 사이클 훅이 접근 방식은 '어쨌든'hacky을 느꼈다. ro을 돌봅니다

앞으로 어디로 가야 할지 잘 모르겠어요.폼 데이터를 스토어에 커밋하고 폼을 다시 마운트하면 다시 얻을 수 있지만, 폼의 부모가 마운트되어 있는 동안에만 존재해야 하는 것을 커밋하는 것이 올바른 방법이라고는 생각하지 않습니다.

Vue를 통해 이를 실현하는 방법을 안내해 주실 수 있습니까?

Form Component의 코드를 데이터에서 computed로 옮겨서 이 문제를 해결할 수 있을 것 같습니다.
계산된 속성은 반응적이기 때문에 initialValues 프로포스트가 최종적으로 데이터를 취득하면 폼에 반영됩니다.
object.assign은 initialValues가 항상 address1, address2 등의 구조를 가지고 있는 경우(처음에는 늘이더라도) 동작합니다.그렇지 않은 경우(예: 초기 값 = {}), 속성별 검사를 수행해야 합니다.

<template>
  <!--Some form fields here, bound to data(){}, ommitted for brevity-->
  <div>selectedAddress.address1</div>
  <div>selectedAddress.address2</div>
</template>
<script>
  export default{
    props:['initialValues'],
    data(){
    },
    computed: {
      selectedAddress() {
        return Object.assign({}, this.initialValues)
      }
    }
  }
</script>

다음 라운드의 폼 값을 유지하려면 selectedAddress를 import를 통해 전달하고 부모 formValues에 적용해야 합니다.

제가 좋아하는 대안으로 Vuex가 있습니다. Vuex는 폼이 스토어에서 초기값을 가져와 작업을 통해 스토어에 다시 게시합니다. 그러면 비동기 작업이 시작되고 스토어가 결과로 업데이트됩니다.기본적으로 displayResults 메서드가 액션이 되지만 비동기화할 필요는 없습니다.기다리다

Vuex는 데이터 흐름 패턴을 공식화하여 보다 쉽게 추론하고 디버깅할 수 있도록 합니다.기본적으로 데이터를 소품으로 전달하거나 방출하는 것에 대해 걱정할 필요가 없습니다.

FormContainer에서 v-if 대신 v-show를 사용하면 FormComponent 값이 재설정되지 않도록 할 수 있습니다.폼 div(및 상태)는 유지되지만 숨깁니다.그러면 부모에게 formValues를 설정할 필요가 없을 수 있습니다.

<template>
  <div v-show="formShown">
    <form-component :initialValues="formValues" @formSubmitted="displayResults"></form-component>
  </div>
  <div v-show="tableShown">
    <table-component :results="fetchedResults" @returnToForm="returnToForm"></table-component>
  </div>
</template>

언급URL : https://stackoverflow.com/questions/46377169/conditional-props-in-vue2

반응형