programing

Vue에서 하위 구성 요소의 계산된 속성에 액세스하는 중

javaba 2022. 7. 10. 11:30
반응형

Vue에서 하위 구성 요소의 계산된 속성에 액세스하는 중

하위 구성요소의 계산된 속성에 액세스하는 적절한 방법은 무엇입니까?다음은 제가 달성하고자 하는 바를 간략하게 보여주는 예입니다(JSFiddle에서도 사용 가능).

const FoobarWidget = {
    template: '<li>a: <input type="text" v-model="value.a" style="width:2em;"> b: <input type="text" v-model="value.b" style="width:2em;"> sum: {{this.sum}} <button @click="die">x</button></li>',
    props: {
        value: {
            type: Object,
            required: true,
        }
    },
    computed: {
        sum() {
            const s = Number(this.value.a) + Number(this.value.b)
            // WARNING eslint - vue:no-side-effects-in-computed-properties
            this.value.sum = s;
            return s;
        }
    },
    methods: {
        die() {
            this.$emit('die');
        }
    }
};

new Vue({
    el: '#app',
    data: {
        foobars: [{
            a: '5',
            b: '6'
        }],
    },
    components: {
        FoobarWidget,
    },
    computed: {
        myJson() {
            return JSON.stringify(this.foobars, null, 2);
        }
    },
    methods: {
        addNew() {
            this.foobars.push({
                a: '1',
                b: '2'
            });
        },
        foobarDead(index) {
            this.foobars.splice(index, 1);
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
  <button @click="addNew()">add foobar</button>
  <h3>Foobars</h3>
  <ul>
    <foobar-widget v-for="(foobar, index) in foobars" :key="index" @die="foobarDead(index)" v-model="foobars[index]"/>
  </ul>
  <h3>JSON</h3>
  <pre>{{myJson}}</pre>
</div>

이 예제를 사용해 보면 알 수 있듯이, 하위 구성요소(a, b 및 계산된 합계)의 값을 변경한 후 상위 구성요소(생성된 JSON)의 변경 사항을 잘 반영하지 않는 경우를 제외하고는 대부분 작동합니다.

질문은 SO:컴포넌트 소품에 대한 계산 속성과 비슷하지만, 이 질문의 OP는 문자열 포맷을 통해 계산된 값을 가지고 있기 때문에 Vue 필터를 사용하는 것이 좋은 해결책입니다.이 경우는 해당되지 않습니다.sum()계산된 속성은 부모 구성 요소와 자식 구성 요소 모두에서 액세스해야 하는 임의 함수일 수 있습니다.

위에서 설명한 방법에서는 프로펠러 오브젝트를 수정하여sum재계산될 때 소유권은 확실히 올바른 방법이 아닙니다. 그래서 질문입니다.이 기능은 정상적으로 동작할 뿐만 아니라 ESLint 경고도 생성합니다.WARNING코멘트(상기 코드로)

상위 항목이 업데이트되지 않는 이유는 Vue가 감지하지 못하는 개체에 속성을 추가하고 있기 때문입니다.

대신

    sum() {
        const s = Number(this.value.a) + Number(this.value.b)
        // WARNING eslint - vue:no-side-effects-in-computed-properties
        this.value.sum = s;
        return s;
    }

당신은 할 것이다

sum() {
    const s = Number(this.value.a) + Number(this.value.b)
    this.$set(this.value, 'sum', s);
    return s;
}

계산된 부작용의 코드 냄새와 소품에서 값을 갱신하는 코드 냄새에도 불구하고, 이것은 여러분이 뭔가 다른 것을 해야 한다는 것을 암시합니다.

잘못 접근하고 계신 것 같군요개체의 값을 합한 속성을 원하는 경우 해당 속성을 구성 요소가 아닌 개체에 추가합니다.

여기 예가 있습니다.

const FoobarWidget = {
  template: '<li>a: <input type="text" v-model="value.a" style="width:2em;"> b: <input type="text" v-model="value.b" style="width:2em;"> sum: {{value.sum}} <button @click="die">x</button></li>',
  props: {
    value: {
      type: Object,
      required: true,
    }
  },
  methods: {
    die() {
      this.$emit('die');
    }
  }
};

const foo = {
  a: 5,
  b: 6,
  // define your property here
  get sum() {
    return +this.a + +this.b
  }
}

new Vue({
  el: '#app',
  data: {
    foobars: [foo],
  },
  components: {
    FoobarWidget,
  },
  methods: {
    addNew() {
      this.foobars.push({
        a: '1',
        b: '2',
        get sum() {
          return +this.a + +this.b;
        }
      });
    },
    foobarDead(index) {
      this.foobars.splice(index, 1);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
  <button @click="addNew()">add foobar</button>
  <h3>Foobars</h3>
  <ul>
    <foobar-widget v-for="(foobar, index) in foobars" :key="index" @die="foobarDead(index)" v-model="foobars[index]" />
  </ul>
  <h3>JSON</h3>
  <pre>{{foobars}}</pre>
</div>

이 방법을 사용하면 컴포넌트의 계산된 속성에 액세스할 필요가 없습니다.

언급URL : https://stackoverflow.com/questions/48950662/accessing-computed-properties-of-child-components-in-vue

반응형