programing

Vue + VUEX + 타입 스크립트 + Vue 라우터컴포넌트가 파괴되지 않음

copysource 2022. 8. 9. 23:28
반응형

Vue + VUEX + 타입 스크립트 + Vue 라우터컴포넌트가 파괴되지 않음

Vue.js 버전= 2 . 3 . 3

모두에게 질문하다.폼 입력에 기반한 데이터 목록을 포함하는 json을 가지고 있습니다.양식 입력에는 모델이 바인딩되어 있으며 기본적으로 앱 상태 트롤 커밋을 업데이트합니다.

체크박스 목록을 렌더링하는 컴포넌트가 있습니다.한 페이지에는 1개의 인스턴스가 있고 다음 페이지에는 3개의 컴포넌트 인스턴스가 있습니다.각 컴포넌트에는 체크박스 목록이 있고 다른 이름이 있습니다.

1페이지에서 2페이지로 이동할 때 1페이지의 checkbox_list 컴포넌트는 파괴된 라이프 사이클 훅을 기동하지 않습니다(다른 컴포넌트가 기동합니다).

2페이지에는 checkbox_list 타입의 컴포넌트 3개와 그 이름, 모델, 옵션이 있습니다.(data함수로 초기화됩니다).타입 체크 박스 리스트의 세 번째 컴포넌트가 기동하지 않는다.created후크, 장착되지 않았거나 장착되지 않았음.렌더링되지만 렌더링되지 않고 이벤트 및 모델이 있으며 vue 디버거에서 모델 배열이 비어 있습니다.문제는 세 번째 컴포넌트 인스턴스(생성된 라이프 사이클 훅이 실행되지 않은 것)에서 체크박스 모델 중 하나를 클릭하면 checkbox_list 컴포넌트 인스턴스의 첫 페이지에서 체크한 모든 것이 모델에 포함되어 있다는 것입니다.

데이터가 해석될 때 구성요소는 기본적으로 루프로 렌더링됩니다.왜 이런 일이 생기는지 아는 사람?고마워요.

제 컴포넌트의 Bellow Code를 참조해 주세요. InputTypes.ts

import Vue from 'vue';
import Component from 'vue-class-component';

import TextInput from './text/TextInput.vue';
import EmailInput from './email/EmailInput.vue';
import RadioGroup from './radio/RadioGroup.vue';
import SelectInput from './select/SelectInput.vue';
import SelectAutocompleteInput from './select/SelectAutocompleteInput.vue';
import PasswordInput from './password/PasswordInput.vue';
import CheckboxGroup from './checkbox/CheckboxGroup.vue';
import AgreementSection from './custom/AgreementSection.vue';
import CvSection from './custom/CVSection.vue';
import SubmitSection from './custom/SubmitSection.vue';


@Component({
  name: 'input-types',
  props: ['field', 'lastPageIndex'],
  components: {
    TextInput,
    EmailInput,
    RadioGroup,
    SelectInput,
    SelectAutocompleteInput,
    PasswordInput,
    AgreementSection,
    CheckboxGroup,
    CvSection,
    SubmitSection
  },
  watch: {
    '$route'($to, $from) {
      let clearFields = this['clearFields'];
      clearFields();
    }
  }
})

export default class InputsTypes extends Vue {
  conditionalFields: object = {fields: []};

  clearFields(): void {
    this.$set(this.conditionalFields, 'fields', []);
  }

  changeHandler(fields): void {
    this.$set(this.conditionalFields, 'fields', fields);
  }

  updateModelValue(data): void {
    console.log(data);
  }
}

InputTypes.vue

<!-- InputTypesComponent -->
<template>
  <div>
    <text-input v-if="field.type == 'text'" :field="field"></text-input>

    <email-input v-else-if="field.type == 'email'" :field="field"></email-input>

    <checkbox-group v-else-if="field.type == 'checkbox_list'" :field="field"></checkbox-group>

    <radio-group v-else-if="field.type == 'radio'" :field="field" :onChange="changeHandler"></radio-group>

    <select-input  v-else-if="field.type == 'select'" :field="field" :onChange="changeHandler"></select-input>

    <select-autocomplete-input  v-else-if="field.type == 'select_autocomplete'" :field="field" :onChange="changeHandler"></select-autocomplete-input>

    <password-input v-else-if="field.type == 'password'" :field="field"></password-input>

    <agreement-section v-else-if="field.type == 'agreement'" :field="field"></agreement-section>

    <div v-else-if="field.type == 'complex_inputs'">
      <label>{{field.label}}</label>
      <div v-for="option, key in field.options" :key="key">
        <input-types :field="option" :onChange="changeHandler"></input-types>
      </div>
    </div>
    <cv-section v-else-if="field.type == 'cv_section'" :field="field"></cv-section>
    <submit-section v-else-if="field.type == 'next_page'" :field="field" :lastPageIndex="lastPageIndex"></submit-section>

    <div v-if="conditionalFields.fields" v-for="field, key in conditionalFields.fields" :key="key">
      <input-types :field="field" :onChange="changeHandler"></input-types>
    </div>
  </div>
</template>

<script lang="ts">
  import InputsTypes from './InputsTypes.ts'
  export default InputsTypes
</script>

CheckboxGroup.ts

import Vue from 'vue';
import Component from 'vue-class-component';


@Component({
  name: 'checkbox-group',
  props: ['field'],
  watch: {
    selected: (e) => {
      console.log(e);
    }
  },
  created(): void {
    let predefinedSelected: Array<string> = [];
    let data: object = {
      'name': this.$props.field.name,
      'value': predefinedSelected
    };

    let updateState = this['updateState'];
    updateState(data);
  }
})

export default class CheckboxGroup extends Vue {
  updateStore(): void {
    let data: object = {
      'name': this.$props.field.name,
      'value': this['selected']
    };
    this.updateState(data);
  }

  updateState(data): void {
    this.$store.commit('SIMPLE_FIELD_UPDATE', data);
  }

  data(): object {
    let predefinedSelected: Array<string> = this.$props.field.selected || [];
    return {
      selected: []
    }
  }
  created(): void {
    console.log('created');
  }
  mounted(): void {
    console.log('mounted');
  }
  destroyed(): void {
    console.log('destroyed');
  }
}

CheckboxGroup.vue

    <template>
  <div class="checkbox-group">
    <div class="row" v-if="field.label">
      <div class="col">
        {{field.label}}
      </div>
    </div>
    <div class="row">
      <div class="form-check col-3" v-for="option, key in field.options" :key="key">
        <label class="form-check-label">
          <input class="form-check-input" v-model="selected" @change="updateStore" type="checkbox" :name="field.name" :value="option.label"/>
          {{option.label}}
        </label>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
  import CheckboxGroup from './CheckboxGroup.ts'
  export default CheckboxGroup
</script>

이는 데이터를 기반으로 런타임에 형태를 변경할 수 있는 구성 요소를 만들 수 있는 가변 구성 요소에 매우 적합합니다.

따라서 복합 유형을 자체 구성요소에 추가한 다음 복합 구성요소 대신input-types사용만 하면 됩니다.

<component :is="field.type" :field="field"></component>

어디에 쓰든

<input-types :field="field"></input-types>

따라서 field.type이 컴포넌트 라벨과 일치하는지 확인해야 합니다.text-inputcomponent field.type은 다음과 같아야 합니다.text-input.

도움이 필요하시면 말씀하세요.

이것은 진짜 문제가 무엇인지 읽고 이해하려고 시도하는 매우 큰 코드 설명/세트입니다.앞으로는 가능한 한 간단한 설명/상황을 시도해 볼 것을 제안할 수 있습니다.

문제의 원인이 v-for와 v-if의 동일한 요소에서의 상호 작용과 관련이 있다고 생각합니다.요소의 각 됩니다.v-if는 v-for의 v-for이다.를 대신 v-if로 입니다.<template>.v-for는 v-for를 실행합니다.

https://vuejs.org/v2/guide/list.html#v-for-with-v-if

그 문제는 쉽게 해결되었다.문제는 URL을 기반으로 뷰를 변경하고 여러 컴포넌트를 렌더링하고 있었는데 일부 컴포넌트는 뷰에서 영속적이어서 Vue는 이전 뷰에서 필요한 컴포넌트와 동일한 컴포넌트로 간주했습니다. 저는 '어느 정도'를 했습니다.key페이지 컴포넌트와 비교하기 때문에 이 상황에서는 다른 컴포넌트로 취급되며 페이지 컴포넌트 내부에서는 얄팍한 비교가 이루어지지 않습니다.

결론:열쇠 잊지 마

언급URL : https://stackoverflow.com/questions/44187158/vue-vuex-typescript-vue-router-component-not-destroyed

반응형