programing

메서드 값을 다른 컴포넌트에 전달하다

prostudy 2022. 7. 31. 21:21
반응형

메서드 값을 다른 컴포넌트에 전달하다

내 컴포넌트에 메서드가 있다.IncomeList이 메서드가 포함되어 있습니다.sumValue. 이 메서드는 서로 다른 숫자를 합산하여 하나의 값(예: 3+5 = 8)을 출력합니다. 다른 컴포넌트에서도 마찬가지입니다.OutputList, 같은 논리가 사용되지만 메서드는sumValueOutput이제 두 값을 모두 다른 컴포넌트(이러한 컴포넌트)에서 사용합니다.WinTotal소품이나 vuex로 뭔가를 시도했지만, 아직 작동하는 제품이 없고 어떻게 시작해야 할지 모르겠어요.도와주셔서 감사합니다!

수입 리스트:

<template>
<div class="container-income">
    <button class="btn btn-info" @click="showModal">show modal</button>
    <div class="hidden-container-income" id="test123">
    <input type="text" class="income-input" placeholder="What needs to be done" v-model="newIncome" @keyup.enter="addincome">
    <input type="text" class="value-input" placeholder="€" v-model="newIncomeValue" @keyup.enter="addValue">
    <transition-group name="fade" enter-active-class="animated fadeInUp" leave-active-class="animated fadeOutDown">
        <income-item v-for="income in incomesFiltered" :key="income.id" :income="income"
                   @removedIncome="removeincome">
        </income-item>
    </transition-group>

    <div class="extra-container">
        <div><label><input type="checkbox" style="display: none" :checked="!anyRemaining" @change="checkAllincomes"></label></div>
        <div>{{ remaining }} elements</div>
    </div>
    <div class="sum-container">
        <div><label> Total Income: </label></div>
        <div>{{ sumValue }} €</div>
    </div>
  </div>
</div>
    </template>
    <script>
    import IncomeItem from './IncomeItem'
    export default {
    name: 'income-list',
    components: {
        IncomeItem,
    },
    data () {
        return {
            newIncome: '',
            newIncomeValue: '',
            idForincome: 3,
            incomes: [
                {
                    'id': 1,
                    'title': 'Finish Vue Screencast',
                    'value': 300,
                    'completed': false,
                    'editing': false,
                },
                {
                    'id': 2,
                    'title': 'Take over world',
                    'value': 315,
                    'completed': false,
                    'editing': false,
                },
                {
                    'id': 3,
                    'title': 'Excellent',
                    'value': 313,
                    'completed': false,
                    'editing': false,
                },
            ]
        }
    },
    computed: {
        remaining() {
            return this.incomes.filter(income => !income.completed).length
        },
        anyRemaining() {
            return this.remaining != 0
        },
        incomesFiltered() {
            return this.incomes
        },
        sumValue() {
            return this.incomesFiltered.reduce((a, c) => a + c.value, 0)
        },
    },
    methods: {
            addincome() {
                if (this.newIncome.trim().length == 0) {
                    return
                }
                this.incomes.push({
                    id: this.idForincome,
                    title: this.newIncome,
                    value: this.newIncomeValue,
                    completed: false,
                })
                this.newIncome = ''
                this.newIncomeValue = ''
                this.this.idForincome++
            },

        removeincome(id) {
            const index = this.incomes.findIndex((item) => item.id == id)
            this.incomes.splice(index, 1)
        },
        checkAllincomes() {
            this.incomes.forEach((income) => income.completed = event.target.checked)
        },
        clearCompleted() {
            this.incomes = this.incomes.filter(income => !income.completed)
        },
        finishedEdit(data) {
            const index = this.incomes.findIndex((item) => item.id == data.id)
            this.incomes.splice(index, 1, data)
        },
        //Same for Value
        addValue() {
            if (this.newIncomeValue.trim().length == 0) {
                return
            }
            this.incomes.push({
                id: this.idForincome,
                title: this.newIncome,
                value: this.newIncomeValue,
                completed: false,
            })
            this.newIncome = ''
            this.newIncomeValue = ''
            this.this.idForincome++
        },
        showModal () {
            if (document.getElementById('test123').style.display == 'none' ) {
                document.getElementById('test123').style.display = 'block';
            }
            else {
                
                
document.getElementById('test123').style.display = 'none'
            }
        },
    },
};
                               </script>

출력 목록:

<template>
<div class="container-output1">
    <button class="btn btn-info1" @click="showModal">show modal</button>
    <div class="hidden-container-output1" id="test1231">
        <input type="text" class="output-input1" placeholder="What needs to be done" v-model="newOutput" @keyup.enter="addoutput">
        <input type="text" class="value-input1" placeholder="€" v-model="newOutputValue" @keyup.enter="addValue">
        <transition-group name="fade" enter-active-class="animated fadeInUp" leave-active-class="animated fadeOutDown">
            <output-item v-for="output in outputsFiltered" :key="output.id" :output="output"
                         @removedoutput="removeOutput">
            </output-item>
        </transition-group>

        <div class="extra-container1">
            <div><label><input type="checkbox" style="display: none" :checked="!anyRemaining" @change="checkAlloutputs"></label></div>
            <div>{{ remaining }} elements</div>
        </div>
        <div class="sum-container1">
            <div><label> Total Output: </label></div>
            <div>{{ sumValueOutput }} €</div>
        </div>
    </div>
</div>
   </template>

   <script>
import OutputItem from './OutputItem'
export default {
    name: 'output-list',
    components: {
        OutputItem,
    },
    data () {
        return {
            newOutput: '',
            newOutputValue: '',
            idForOutput: 3,
            outputs: [
                {
                    'id': 1,
                    'title': 'Finish Vue Screencast',
                    'value': 300,
                    'completed': false,
                    'editing': false,
                },
                {
                    'id': 2,
                    'title': 'Take over world',
                    'value': 315,
                    'completed': false,
                    'editing': false,
                },
                {
                    'id': 3,
                    'title': 'Excellent',
                    'value': 311,
                    'completed': false,
                    'editing': false,
                },
            ]
        }
    },
    computed: {
        remaining() {
            return this.outputs.filter(output => !output.completed).length
        },
        anyRemaining() {
            return this.remaining != 0
        },
        outputsFiltered() {
            return this.outputs
        },
        sumValueOutput() {
            var outputValue = this.outputsFiltered.reduce((a, c) => a + c.value, 0);
            return outputValue;
        },
    },
    methods: {
        addOutput() {
            if (this.newOutput.trim().length == 0) {
                return
            }
            this.outputs.push({
                id: this.idForOutput,
                title: this.newOutput,
                value: this.newOutputValue,
                completed: false,
            })
            this.newOutput = ''
            this.newOutputValue = ''
            this.this.idForOutput++
        },

        removeOutput(id) {
            const index = this.outputs.findIndex((item) => item.id == id)
            this.outputs.splice(index, 1)
        },
        checkAlloutputs() {
            this.outputs.forEach((output) => output.completed = event.target.checked)
        },
        clearCompleted() {
            this.outputs = this.outputs.filter(output => !output.completed)
        },
        finishedEdit(data) {
            const index = this.outputs.findIndex((item) => item.id == data.id)
            this.outputs.splice(index, 1, data)
        },
        //Same for Value
        addValue() {
            if (this.newOutputValue.trim().length == 0) {
                return
            }
            this.outputs.push({
                id: this.idForOutput,
                title: this.newOutput,
                value: this.newOutputValue,
                completed: false,
            })
            this.newOutput = ''
            this.newOutputValue = ''
            this.this.idForOutput++
        },
        showModal () {
            if (document.getElementById('test1231').style.display == 'none' ) {
                document.getElementById('test1231').style.display = 'block';
            }
            else {
                document.getElementById('test1231').style.display = 'none'
            }
        }

    }
}
            </script>

즉시 사용할 수 있는 두 가지 방법이 있습니다.

1) 버스를 이용한 데이터 전달

Vue에서는 하위 구성 요소와 상위 구성 요소 간에 데이터를 상당히 쉽게 전달할 수 있습니다.하위 구성 요소에서 전송할 데이터를 이벤트로 내보냅니다.

this.$emit('event-name', payload)

...그리고 부모에서는 이벤트를 듣고 데이터를 사용하여 다음과 같은 작업을 수행합니다.

<child-component @event-name="doSomething($event)" />

그러나 두 구성 요소 간에 데이터를 전달하는 것은 더 까다로워집니다.자녀-부모-자녀 전략을 통해 컴포넌트에서 컴포넌트로 데이터를 전달할 수 있지만 이는 지루해집니다.대신 두 하위 구성 요소에서 가져오고 두 구성 요소 간에 직접 이벤트를 내보내는 Vue 인스턴스인 버스를 생성할 수 있습니다.

버스는 쉽게 만들 수 있습니다. 두 줄을 제외한 모든 코드가 필요합니다.

// Bus.js
import Vue from "vue";

export const Bus = new Vue();

따라서 자녀 컴포넌트에서는IncomeList그리고.OutputList) 버스를 Import 합니다.

import { Bus } from "@/Bus";

...의 가치를 가진 이벤트를 방출합니다.sumValue(인IncomeList)

sumValue() {
    const sumVal = this.incomesFiltered.reduce((a, c) => a + c.value, 0);
    Bus.$emit("sumvalue-change", sumVal);
    return sumVal;
}

...그리고.sumOutputValue(인OutputList):

sumValueOutput() {
    const outputValue = this.outputsFiltered.reduce((a, c) => a + c.value, 0);
    Bus.$emit("sumvalueoutput-change", outputValue);
    return outputValue;
}

그럼 인WinTotal.vue, 컴포넌트내의 버스를 Import 해, 이러한 이벤트를 수신합니다.created후크:

created() {
    Bus.$on("sumvalue-change", (sumvalue) => (this.sumValue = sumvalue));
    Bus.$on("sumvalueoutput-change", (sumvalueoutput) => (this.sumValueOutput = sumvalueoutput));
}

이제 를 사용할 수 있습니다.sumValue그리고.sumValueOutputWinTotal원하는 대로 변경할 때마다 자동으로 업데이트됩니다.IncomeList또는OutputList.

발광 가스 가공의

다음은 이 솔루션을 보여주는 샌드박스입니다.

하지만 이 방법에는 단점이 있습니다.당신의 말을 하세요App.vue다음과 같습니다.

// App.vue
<template>
  <div id="app">
    <IncomeList />
    <OutputList />
    <WinTotal />
  </div>
</template>

이 경우 둘 다IncomeList그리고.OutputList에 제시되다 WinTotal의 초기값은 다음과 같습니다.sumValue그리고.sumValueOutput보다 먼저 방출됩니다. WinTotal이 사건들을 듣기 시작했다.따라서,WinTotal초기값을 수신하지 않다sumValue그리고.sumValueOutput(아래 참조).

방사 파괴된

당신이 볼 수 있듯이.WinTotal처음에는 값으로 업데이트되지 않지만 변경 시 정상적으로 업데이트됩니다.회피책으로서는,<WinTotal />전에<IncomeList />그리고.<OutputList />하지만 그것이 항상 가능한 것은 아니다.물론 다른 방법으로도 이 문제를 해결할 수 있지만, 구현이 지루할 수 있으므로 번거롭게 할 필요가 없습니다.자, 여기 대안이 있습니다.

2) VueX를 사용한 데이터 전달

보다 심플한 솔루션은 VueX를 사용하는 것입니다.이전에 VueX를 사용해 본 적이 있다고 하셨기 때문에, VueX에 대해 조금 알고 계실 거라고 생각합니다만, 불명확한 점이 있으면 알려 주십시오.

VueX가 이미 설정되어 있는 경우, 에 다음 값을 작성합니다.sumValueIncome ★★★★★★★★★★★★★★★★★」sumValueOutput업데이트:

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    sumValueIncome: null,
    sumValueOutput: null
  },
  mutations: {
    updatesumValueIncome(state, newvalue) {
      state.sumValueIncome = newvalue;
    },
    updatesumValueOutput(state, newvalue) {
      state.sumValueOutput = newvalue;
    }
  },
  actions: {},
  modules: {}
});

ㅇㅇㅇㅇ에서IncomeList, 업데이트, 업데이트 합니다.sumValueIncome 솔루션과 (단, '사용할 수 없습니다'(단, '사용할 수 없습니다)VueX(미국의)

sumValueIncome() {
  const sumValueIncome = this.incomesFiltered.reduce((a, c) => a + c.value, 0);
  this.$store.commit("updatesumValueIncome", sumValueIncome);
  return sumValueIncome;
}

...또한OutputList:

sumValueOutput() {
  const outputValue = this.outputsFiltered.reduce((a, c) => a + c.value, 0);
  this.$store.commit("updatesumValueOutput", outputValue);
  return outputValue;
}

»WinTotal도우미를 사용하여 동적으로 갱신된 값을 사용하여 계산된 속성을 생성할 수 있습니다.sumValue ★★★★★★★★★★★★★★★★★」sumValueOutput:

<template>...</template>
<script>
import { mapState } from "vuex";

export default {
  name: "win-total",
  computed: mapState(["sumValueIncome", "sumValueOutput"]),
};
</script>

...이제 준비는 다 됐어!

vuex의 매개에 의한

다음은 이 솔루션을 보여주는 샌드박스입니다.


언급URL : https://stackoverflow.com/questions/65535047/pass-method-value-to-another-component

반응형