programing

Vuejs : 오브젝트를 프로펠러로 전달하여 컴포넌트가 서브 오브젝트를 갱신하도록 하는 방법

prostudy 2022. 5. 29. 09:20
반응형

Vuejs : 오브젝트를 프로펠러로 전달하여 컴포넌트가 서브 오브젝트를 갱신하도록 하는 방법

개체를 소품으로 받아들이고 해당 개체의 다른 속성을 수정하여 동기화 또는 내보내기 이벤트를 사용하여 부모에게 값을 반환할 수 있는 구성 요소를 만들려고 합니다.이 예는 효과가 없겠지만, 단순히 제가 달성하려는 것을 보여주기 위한 것입니다.

다음은 제가 달성하고자 하는 일의 일부입니다.

Vue.component('child', {
  template: '#child',
  
  //The child has a prop named 'value'. v-model will automatically bind to this prop
  props: ['value'],
  methods: {
    updateValue: function (value) {
      //Not sure if both fields should call the same updateValue method that returns the complete object, or if they should be separate
      this.$emit('input', value);
    }
  }
});

new Vue({
  el: '#app',
  data: {
    parentObject: {value1: "1st Value", value2: "2nd value"}
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
  <p>Parent value: {{parentObject}}</p>
  <child v-model="parentObject"></child>
</div>

<template id="child">
   <input type="text" v-bind:value.value1="value" v-on:input="updateValue($event.target.value)">
   <input type="text" v-bind:value.value2="value" v-on:input="updateValue($event.target.value)">
</template>

전달되는 오브젝트를 소품으로 수정하면 안 됩니다.대신 하위 구성 요소에 새 데이터 속성을 생성하고 프로펠러 개체의 복사본으로 초기화해야 합니다.

그럼, 저는 그냥...v-model하위 구성요소의 각 입력에 대해 내부 값에 심층 관찰자를 추가하여 이 값을 방출합니다.update내부 값이 변경될 때마다 표시됩니다.

Vue.component('child', {
  template: '#child',
  props: ['value'],
  data() {
    return { val: {...this.value} };
  },
  watch: {
    val: {
      deep: true,
      handler(value) {
        this.$emit('input', value);
      }
    }
  }
});

new Vue({
  el: '#app',
  data: {
    parentObject: {value1: "1st Value", value2: "2nd value"}
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

<div id="app">
  <p>Parent value: {{parentObject}}</p>
  <child v-model="parentObject"></child>
</div>

<template id="child">
  <div>
    <input type="text" v-model="val.value1">
    <input type="text" v-model="val.value2">
  </div>
</template>

이 예에서는 소품(소품)을 얄팍하게 복사했습니다.{...this.value}오브젝트에 네스트된 속성이 없기 때문입니다.그렇지 않은 경우 상세 복사가 필요할 수 있습니다.JSON.parse(JSON.stringify(this.value))).

#app, 해야 한다.parentObject,것은 아니다.parentValue.

아이였을 때, 넌 두 개를 가졌지inpyt단, 루트 요소가1개 필요해요다음 예에서는 다음 예제를 작성했습니다.<div>컴포넌트의 루트 요소.

부모를 업데이트하려면 이벤트를 내보냅니다.이 접근 방식은 하위에서 상위 속성을 수정하지 않으므로 일방향 데이터 흐름이 중단되지 않습니다.

Vue.component('child', {
  template: '#child',
  
  //The child has a prop named 'value'. v-model will automatically bind to this prop
  props: ['value']
});

new Vue({
  el: '#app',
  data: {
    parentObject: {value1: "1st Value", value2: "2nd value"}
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
  <p>Parent value: {{parentObject}}</p>
  <child v-model="parentObject"></child>
</div>

<template id="child">
<div>
   <input type="text" v-bind:value="value.value1" v-on:input="$emit('input', {value1: $event.target.value, value2: value.value2})">
   <input type="text" v-bind:value="value.value2" v-on:input="$emit('input', {value1: value.value1, value2: $event.target.value})">
</div>
</template>

에 대해서<input>s: 각 파일을 부모의 속성에 바인드할 수 있습니다.value그런 다음 편집 시 해당 속성만 수정하는 이벤트를 내보냅니다(v-on:input="$emit('input', {value1: $event.target.value, value2: value.value2})상대방의 가치를 유지할 수 있습니다.그 결과 부모가 갱신됩니다.

속성이 많으면 두 번째에서 바꿀 수 있습니다.input예를 들어 다음과 같습니다.

$emit('input', {value1: value.value1, value2: $event.target.value})

와 함께

$emit('input', Object.assign({}, value, {value2: $event.target.value}))


템플릿에서 직접 내보내는 대신 메서드 사용

이전 데모는 이해하기 쉽고(원래 코드로부터의 변경은 적기 때문에) 직접적이지만, 보다 컴팩트한 접근방식은 메서드(예:updateValue를 템플릿에서 재사용합니다.

Vue.component('child', {
  template: '#child',
  
  //The child has a prop named 'value'. v-model will automatically bind to this prop
  props: ['value'],
  methods: {
    updateValue: function(propertyName, propertyValue) {
      this.$emit('input', Object.assign({}, this.value, {[propertyName]: propertyValue}))
    }
  }
});

new Vue({
  el: '#app',
  data: {
    parentObject: {value1: "1st Value", value2: "2nd value"}
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
  <p>Parent value: {{parentObject}}</p>
  <child v-model="parentObject"></child>
</div>

<template id="child">
<div>
  <input type="text" v-bind:value="value.value1" v-on:input="updateValue('value1', $event.target.value)">
  <input type="text" v-bind:value="value.value2" v-on:input="updateValue('value2', $event.target.value)">
</div>
</template>

위의 데모는 보시는 바와 같이 이미 사용하고 있습니다.Object.assign()즉, 무제한의 속성을 처리합니다.

불가능합니다.그것을 요구하는 비공개 이슈가 있다.이것이 제가 찾은 가장 짧은 방법입니다.

대본

Vue.component('child', {
  template: `
    <div>
        <input :value="parent.foo" @change="$emit('update:parent', $event.target.value)" />
    </div>
  `,
  props: {
    parent: {
      type: Object
    }
  }
})

new Vue({
  el: '#app',
  data: () =>  ({
    parent: {foo: 'a', bar: 'b'}
  }),

  methods: {
    mutate (value) {
        this.parent.foo = value
    }
   }
})

템플릿

<div id="app">
  {{parent}}
  <child :parent="parent" @update:parent="mutate"></child>
</div>

https://jsfiddle.net/5k4ptmqg/475/

<TradeTableItem v-for="(debtReserve, index) in debtReserves" :key="debtReserve.id" :debtReserve="debtReserve" :market="market" :id="'order_by_' + index"></TradeTableItem>

상위 단계에서는 각 행에 대한 ID를 생성했습니다.

또한 TradeTableItem(템플릿을 채우는 경우 테이블 행)에 ID를 :id="this.id"로 입력합니다.여기서 this.id은 소품의 일부입니다.

도움이 되었으면 좋겠다

하지 않는 props는 컴포넌트 「Components Atribute」에 할 수 .$attrs을 사용하다

부모 내

<child v-model="parentObject" />

자녀는 '자녀'가 하는 값 입니다.v-model할 수 있습니다.

$attrs.value.value1

그리고 이것은 반응적이다.

데모는 이쪽

언급URL : https://stackoverflow.com/questions/49072799/vuejs-how-to-pass-an-object-as-prop-and-have-the-component-update-sub-objects

반응형