programing

구성 요소(특히 내포됨)를 사용할 때 속성, 데이터 및 계산된 값의 혼동

firstcheck 2022. 7. 23. 11:25
반응형

구성 요소(특히 내포됨)를 사용할 때 속성, 데이터 및 계산된 값의 혼동

어떻게 하면 부모로부터 재산을 물려받아 자녀에게 갱신하고 그 변경 사항을 부모에게 전달할 수 있을지 정말 혼란스럽다.참고로 그것은 효과가 있는 것처럼 보이지만 내가 읽은 모든 것을 보면 그것은 그것을 하는 올바른 방법이 아니다.

작성 폼을 "조작"하는 부모 컴포넌트가 있습니다.아티팩트의 새 인스턴스가 생성되어 다른 위치에서 사용되는 "작성" 구성 요소로 전달됩니다.create component에는 몇 가지 공통 속성이 있지만 슬롯을 통해 부모 수준에서 사용자 지정 속성을 추가할 수 있습니다.

ArtactCreate 구성 요소 내에서 해당 프로포트의 "클론"을 양식 및 사용자 지정 속성으로 전달합니다.

"prop" 값을 가져와서 내부적으로 작업한 다음 최종 결과를 ArtifactCreate 구성 요소에 버블링하는 방법을 이해하려고 합니다. 이 구성 요소는 상위 구성 요소에 버블링합니다.

"자녀" 구성 요소(ArtifactCreateForm 및 DatasetProperties)에는 추가 메서드가 없으며 전달된 프로펠러 참조를 직접 업데이트합니다.Dataset Properties는 다른 장소에서도 사용할 수 있습니다.

대부분의 경우 메인 상호작용을 처리하고 싶지만 일부 모델을 하나 이상의 컴포넌트에 전달해야 하는 "부모"가 있습니다.이러한 모델은 자녀에게 전달될 수 있습니다.

구조는 다음과 같습니다.

Parent Component (somewhat like the controller handling main actions)
   |
   |--- View Component (takes in 'artifact' prop and passes it down)
            |
            |--- Child Component
                     |
                     |--- GrandChild 1..x
   |-----------------|--- GrandChild (through slot)

속성과 데이터 및/또는 계산된 값의 관계와 손자 손녀의 데이터를 올바르게 다루는 방법에 대해 정말 혼란스럽습니다.데이터를 전달하고 이벤트를 위로 내보낸다는 개념도 괜찮고, 원시적인 속성으로 어떻게 해야 하는지 알 것 같은데, 많은 속성을 가진 오브젝트로 어떻게 하면 좋을까요?

질문은 다음과 같습니다.

  1. 소품을 전달하고 컴포넌트 내부에서 (복사본으로) 처리한 후 부모에게 다시 버블을 표시하는 올바른 방법은 무엇입니까?

  2. 하위 컴포넌트에서 이벤트를 버블링하는 것이 부모 컴포넌트에 도달할 때까지 반복하는 유일한 방법입니까?

  3. 개별 값이 아닌 "객체"를 제안/데이터로 사용하고 있습니다.참조가 업데이트(복사본)된 후 부모(원하는 대로)로 버블됩니다.이게 바른 길이야?

(참고로 자바에서 Vue로 왔기 때문에 나에게는 전혀 새로운 세상이다.)

상위 컴포넌트

이것이 작성 컴포넌트에 대한 입력입니다.인스턴스(이 경우 새 인스턴스)를 관리하고 내부적으로 인스턴스를 복제하는 ArtifactCreate 구성 요소로 전달합니다.업데이트된 복사본은 저장된 위치로 다시 버블됩니다.

<template>
  <div>
    <artifact-header/>
    <v-container fluid>
      <!-- List -->
      <reference-list
        :paths="paths"
        @open="load"/>
      <!-- Create Artifact -->
      <artifact-create
        :advanced="true"
        :artifact="newArtifact"
        :title="newTitle"
        @save="save">
        <template #default="{ model }">
          <dataset-properties :artifact="model"/>
        </template>
      </artifact-create>
    </v-container>
  </div>
</template>

지원 대상자:

 computed: {
    newArtifact: {
      get(): Dataset {
        return newDataset();
      }
    }
 },
  methods: {
    save(item: Dataset){
      this.$store.dispatch("saveDataset", item);
    },

아티팩트 생성 구성 요소(하위/컨테이너 구성 요소)

<app-dialog
  :title="title"
  :visible="visible"
  @action="save"
  @close="close">
  <v-tabs v-if="advanced"
    v-model="tab"
    grow>
    <v-tab>Basic</v-tab>
    <v-tab>Advanced</v-tab>
    <!-- Basic Properties -->
    <v-tab-item :key="'Basic'">
      <artifact-create-form :artifact="internal"/>
    </v-tab-item>
    <!-- Advanced Properties -->
    <v-tab-item :key="'Advanced'">
      <slot :model="internal"/>
    </v-tab-item>
  </v-tabs>
  <!-- Basic Properties ONLY -->
  <artifact-create-form v-else 
    :artifact="internal"/>
</app-dialog>

또, 다음의 기능이 서포트되고 있습니다.

export default Vue.extend({
  name: "ArtifactCreate",
  props:{
    artifact: {
      type: Object as Prop<IArtifact>,
      default: {}
    },
  },
  computed:{
    internal: {
      get(): IArtifact {
        return clone(this.artifact);
      },
    }
  },
  methods: {
    save(item) {
      this.$emit('save', this.internal);
      this.visible = false;
    },
  },
});

ArtactCreateForm 구성 요소(ArtactCreate의 하위 항목)

<template>
  <v-form>
    <v-text-field
      v-model="artifact.name"
      label="Name*" 
      required>
    </v-text-field>
  </v-form>
</template>

지원 대상자:

export default Vue.extend({
  name: "ArtifactCreateForm",
  props:{
    artifact: {
      type: Object as Prop<IArtifact>,
      default: {}
    },
  },
});

DatasetProperties 구성 요소(ArtactCreate의 하위 항목/슬롯을 통해 상위 항목에 등록됨)

<template>
  <v-form>
    <v-text-field 
      v-model="artifact.source"
      label="Source">
    </v-text-field>
    <v-text-field 
      v-model="artifact.primaryKey"
      label="Primary Key">
    </v-text-field>
  </v-form>
</template>

지원 대상자:

export default Vue.extend({
  name: 'DatasetProperties',
  props:{
    artifact: {
      type: Object as Prop<Dataset>,
      default: {}
    }
  },
})

Vuex를 사용하고 있어 사용할 수 있지만 새로운 오브젝트를 작성하기 위해서는 과잉인 것 같습니다.그러나 적절한 장소와 타이밍을 찾기 위해 노력하는 데이터 작업 방식과 유사합니다.

복잡한 모델 및 양식 처리는 간단하지 않으며 특히 개체에 v-model을 사용하려는 경우 사용자 지정 구성 요소 v-model 구현을 사용하여 복잡한 양식을 처리하는 좋은 예가 거의 없습니다.아래에 제 추천을 해 보겠습니다.

  1. 소품을 전달하고 컴포넌트 내부에서 (복사본으로) 처리한 후 부모에게 다시 버블을 표시하는 올바른 방법은 무엇입니까?

초기 것이 따라 :artifact="newArtifact" @save="save"그럼 그렇게 해야겠네요.바꿔 말하면, 당신의 부모 컴포넌트는 좋아 보입니다.

에 대한 컴포넌트에서는 할 수 있습니다.v-model아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.이하를 참조해 주세요.

  1. 하위 컴포넌트에서 이벤트를 버블링하는 것이 부모 컴포넌트에 도달할 때까지 반복하는 유일한 방법입니까?

첫 번째 질문에서 지적하신 바와 같이 "Vue way" 방법은 -> 데이터 다운 및 이벤트 업입니다. 까지 할 수 있다v-model remember (기억)v-model="model"기본적으로 의 줄임말이다:value="model" @input="model = $event"그러나 모델이 개체일 경우 이 문제가 약간 복잡해집니다. 위에서 설명한 것처럼 복잡한 개체를 모델로 하는 사용자 지정 구성 요소 v-model을 처리하는 방법에 대한 좋은 예는 거의 없습니다.3번입니다.

  1. 개별 값이 아닌 "객체"를 제안/데이터로 사용하고 있습니다.참조가 업데이트(복사본)된 후 부모(원하는 대로)로 버블됩니다.이게 바른 길이야?

@bivala answer에서 지적된 이유로 참조에 의한 데이터 업데이트 사용은 베스트 프랙티스로 간주되지 않습니다.또한 이벤트 업 접근 방식도 분석합니다.이상적으로는 자녀 컴포넌트ArtifactCreateForm그리고.DatasetProperties는 v-model 기능을 구현해야 합니다.앞서 설명한 바와 같이 사용자 지정 구성 요소에서 특히 개체에 v-model을 구현하는 작업은 생각보다 원활하지 않습니다.그러나 도우미 기능을 구현하여 조금 더 쉽게 만들 수 있습니다.

예를 들어, 에 v-model을 구현하는 경우ArtifactCreateForm컴포넌트는 다음과 같습니다.

<template>
  <v-form>
    <v-text-field
      :value="value.name"
      @input="update(m => (m.name = $event))
      label="Name*" 
      required>
    </v-text-field>
    <v-text-field
      :value="value.description"
      @input="update(m => (m.description = $event))
      label="Description" 
      required>
    </v-text-field>
  </v-form>
</template>


export default Vue.extend({
  name: 'ArtifactCreateForm',
  props:{
    value: {
      type: Object as Prop<IArtifact>
    }
  },
  methods: {
    update(cb: (m: IArtifact) => void) {
      const model = clone(this.value);
      cb(model);
      this.$emit("input", model);
    }
  }
})

이를 다음과 같이 사용할 수 있습니다.

<app-dialog
  :title="title"
  :visible="visible"
  @action="save"
  @close="close">

  <artifact-create-form v-model="internal"/>

</app-dialog>

참고로 다음 블로그 게시물은 사용자 지정 구성 요소에 개체를 사용하여 v-model을 구현하는 방법에 대해 많은 도움을 주었습니다. https://simonkollross.de/posts/vuejs-using-v-model-with-objects-for-custom-components

소품을 전달하고 컴포넌트 내부에서 (복사본으로) 처리한 후 부모에게 다시 버블을 표시하는 올바른 방법은 무엇입니까?

카피로서, 당신이 했던 것처럼ArtifactCreate: 프로펠을 복제하여 원하는 방식으로 변환하고 필요에 따라 이벤트와 함께 부모에게 보냅니다.

그러나 자녀 컴포넌트에 자체 내부 값이 필요하지 않은 경우 프로펠을 복제하지 말고 이벤트를 내보내고 부모 컴포넌트에 변이를 맡겨야 합니다.아이에게는 다음과 같이 나타납니다.

<v-text-field 
  :value="artifact.source"
  label="Source"
  @input="$emit('updateSource', $event)"
>

이 예에서 이상한 점은 부모가 방금 작성한 데이터를 자식 구성 요소가 복제한다는 것입니다.아이가 전화를 걸면 안 될까요?newDataset()?

하위 컴포넌트에서 이벤트를 버블링하는 것이 부모 컴포넌트에 도달할 때까지 반복하는 유일한 방법입니까?

네, 적절한 유일한 방법(다음 답변 참조)

개별 값이 아닌 "객체"를 제안/데이터로 사용하고 있습니다.참조가 업데이트(복사본)된 후 부모(원하는 대로)로 버블됩니다.이게 바른 길이야?

에서 무엇을 했는가ArtifactCreateForm DatasetProperties동작하지만 안티 패턴으로 간주됩니다.그 이유는 데이터가 부모 컴포넌트에 존재하며 하위 컴포넌트에 의해 변환되며 변환의 소스가 부모에 의해 불분명하기 때문입니다.구성 요소 계층이 복잡해질 경우 유지 관리 문제가 발생할 수 있습니다.올바른 방법은 이벤트를 보내는 것입니다.

그렇기 때문에 컴포넌트를 신중하게 분할해야 합니다.정말 재사용 가능성이 있습니까?ArtifactCreateForm ★★★★★★★★★★★★★★★★★」DatasetProperties그렇지 않다면, 여러분은 의 '아까보다', '아까보다', '아까보다'만 고집하면 여러분의 을 더 수 ArtifactCreate★★★★★★ 。

언급URL : https://stackoverflow.com/questions/64812098/confusion-of-properties-data-and-computed-values-when-working-with-components

반응형