Ограничить событие @click для динамически создаваемого элемента с помощью v-for элементом, для которого он вызывается - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть компонент, который генерирует div для каждого элемента в массиве, используя v-for. Чтобы получить больше информации о компоненте, щелкните значок, который использует данные API и отображает их под значком. В настоящее время он отображает извлеченную информацию под каждым элементом в массиве вместо того элемента, который вызывается. Как я могу это исправить? (плохо знакомый с vue. js)

Strain.vue
<template>
<div>
    <div id="strain-container" 
    v-for="(strain, index) in strains"
    :key="index"
    >
        <h3>{{ strain.name }}</h3>
        <p>{{ strain.race }}</p>
        <i class="fas fa-info-circle" @click="getDetails(strain.id)"></i>
        <strain-description :strainData="strainData"></strain-description>
    </div>
</div>
</template>

<script>
import axios from 'axios';
import strainDescription from './strainDescription'

export default {
    props: ['currentRace'],
    components: {
        'strain-description': strainDescription,
    },
    data(){
        return{
            strains: [],
            apiKey: 'removed-for-stack-overflow',
            strainData: {},
        }
    },
    methods: {
        getDetails: function(id){
            const descApi = fetch(`https://strainapi.evanbusse.com/${this.apiKey}/strains/data/desc/${id}`);
            const effectApi = fetch(`https://strainapi.evanbusse.com/${this.apiKey}/strains/data/effects/${id}`);
            const flavourApi = fetch(`https://strainapi.evanbusse.com/${this.apiKey}/strains/data/flavors/${id}`);
            axios.all([descApi, effectApi, flavourApi])
            .then((values)=> axios.all(values.map(value => value.json())))
            .then((data) => {
                this.strainData = data;
            });
        }
    },

Затем выведите данные в компоненте описания деформации:

strainDescription.vue
<template>
    <div id="strain-description">
        <p>{{ strainData[0].desc }}</p>
        <p>{{ strainData[1] }}</p>
        <p>{{ strainData[2] }}</p>
    </div>
</template>

<script>
export default {
    props: ['strainData'],
}
</script>

Понятно (хотя и не мне), что это выводит их в каждый экземпляр "контейнера-штамма", а не экземпляр, к которому он обращен. Любая помощь приветствуется!

1 Ответ

0 голосов
/ 29 апреля 2020

Добавьте штамм Data к штамму в массиве штаммов. Итак, сначала вы можете передать индекс в функцию щелчка

<i class="fas fa-info-circle" @click="getDetails(strain.id, index)"></i>

, затем вы можете обновить массив штаммов по индексу с вашими данными

getDetails: function(id, index){
            const descApi = fetch(`https://strainapi.evanbusse.com/${this.apiKey}/strains/data/desc/${id}`);
            const effectApi = fetch(`https://strainapi.evanbusse.com/${this.apiKey}/strains/data/effects/${id}`);
            const flavourApi = fetch(`https://strainapi.evanbusse.com/${this.apiKey}/strains/data/flavors/${id}`);
            axios.all([descApi, effectApi, flavourApi])
            .then((values)=> axios.all(values.map(value => value.json())))
            .then((data) => {
                this.strains[index].strainData = data;
            });
}

, а затем вернуться в шаблон, который вы можете отобразить например,

<strain-description :strainData="strain.strainData"></strain-description>

Бонус к этому заключается в том, что вы можете проверить, существует ли штамм DataData для штамма, по которому щелкнули, проверяя, определен ли штамм [index] .strainData, прежде чем выполнять вызов API

РЕДАКТИРОВАТЬ

Если шаблон не обновляется, вам может понадобиться использовать vue, установленный для принудительного рендеринга

this.$set(this.strains[index], 'strainData', data);
...