IT이야기

Vue의 하위 구성 요소와 개체 속성 동기화

cyworld 2022. 3. 8. 21:54
반응형

Vue의 하위 구성 요소와 개체 속성 동기화

컨텍스트

나는 Typecript 3.5.3의 클래스 기반 구성요소를 사용하여 Vue.js 2.6.10에서 많은 입력을 가진 큰 양식을 만들고 있다.(아래 코드 스니펫에서 TS가 문제가 아니라는 것을 확신하기 때문에 JS로 변환했다.)사용자를 압도하지 않기 위해 양식은 여러 구성 요소로 분해되며, 한 번에 한 개만 사용자에게 보여진다.

상위 구성요소

<template>
    <form>
        <Basic :Container.sync="Container"/>
        <!-- More custom components -->
        <output>{{Container.name}}</output>
    </form>
</template>

Container개체는 수집될 모든 데이터의 래퍼입니다.알다시피, 내가 모든 물체를 어린이 구성요소에만 전달하도록 요청된 모든 물체를 전달하고 있다.이것은 의견이 분분해 보일지 모르지만, 나는 이유가 있다.

Form 구성 요소는 다음과 같이 요약된다.

// Imports left out for brevity
@Component({ components: {  Basic, }, })
export default class Form extends Vue {
    private Container
    async created() {
        this.Container = {
            name: null
        }
        setInterval(()=>{console.log(this.Container.name)}, 5000)
        // Logs whatever will be entered in the input in the Basic component
    }
}

하위 구성 요소

참조된 구성 요소Basic일반 입력 요소:

<template>
    <input v-model="Container.name" @input="emitUpdate">
</template>

동일한 사소한 구성 요소 정의:

// Imports left out for brevity
@Component({})
export default class Basic extends Vue {
    @Prop() Container
    emitUpdate() {
        console.log(this.Container.name) // Logs whatever was entered in the input
        this.$emit('update:container', this.Container)
    }
}

문제

내가 기대하고 있는 것은 업데이트할 컨테이너와, 그리고<output>현재 이름을 표시하는 첫 번째 HTML 조각에서.그러나 변수가 변경되더라도 두 콘솔 로그가 모두 입력 값을 올바르게 등록한다는 것을 증명했듯, 그것은 변수가 변경되지 않는다.

Vue의 반응성으로 인해 변경사항이 등록되지 않는 것 같다.ContainerHTML을 다시 렌더링하지 않는 객체. 어떻게 수정하지?

시도된 솔루션

다음을 사용하여 업데이트 이벤트에 대해 명시적으로 청취해 보십시오.<Basic … :Container.sync="Container" @Container="Container = $event" />, 그러나 소용이 없었다.

Vue가 개체 속성의 변화에 반응하지 않을 수도 있다고 생각함(결국 개체를 관찰하려면deep또한 설정되는 옵션) 컨테이너의 속성을 개별적으로 전달하려고 시도했는데, 다음과 같은 변경으로 이어졌다.

양식의 html에서 객체는 v-bind에 대한 인수로 사용된다(사용 및 사용 안 함).@update:name):

<Basic … v-bind.sync="Container" @update:name="name=$event"/>

그리고 아동 구성 요소에서 나는 "너희들은 소품을 바꾸지 않을 것이다" 경고를 피하기 위해 게이터와 세터로 바꾸었다.

<input v-model="Name" @input="emitUpdate">`
@Prop() name
get Name() {return this.name }
set Name(newName) {this.$emit('update:name', newName)}

내가 보기엔 문제는 네가 초기화한거야Container내면에 이의를 제기하다created갈고리를 걸면 안 되잖아상태 일부를 반응성으로 만들려면 초기 데이터로 초기화해야 한다(또는 Vue.observable API 사용).나는 TS에 대해서는 잘 모르지만 문서를 보면 네가 해야 할 일은 ...의 선에 따른 것이라고 생각한다.

@Component({ components: {  Basic, }, })
export default class Form extends Vue {
    Container: object = {
        name: null
    }
}

Vue는 우리가 소품을 변이하는 것을 허락하지 않기 때문에 우리는 우리의 로컬 카피를 만들어야 한다.Container, 그러니까 a를 사용하자.computed그것을 위한 재산우리가 이 숙박시설에 접근하려고 할 때, 우리는Component, 그러나 우리가 그것을 설정하기를 원할 때 우리는 단지 우리의 부모 구성요소에 새로운 가치로 이벤트를 촉발한다.Component우리가 이겨낼 수 있다는 것을props.

참조

<Basic v-model="container" />

// Basic.vue
<input v-model="localContainer.name">

props: {
  value: {
    type: Object,
    required: true
  }
},
computed: {
  localContainer: {
    get() {
      return this.value
    },
    set(container) {
      this.$emit('input', container)
    }
  }
}

참조URL: https://stackoverflow.com/questions/57170463/syncing-an-object-property-with-child-components-in-vue

반응형