Home > Software design >  How do have unique variables for each dynamically created buttons/text fields?
How do have unique variables for each dynamically created buttons/text fields?

Time:11-29

I'm trying to create buttons and vue element inputs for each item on the page. I'm iterating through the items and rendering them with v-for and so I decided to expand on that and do it for both the rest as well. The problem i'm having is that I need to to bind textInput as well as displayTextbox to each one and i'm not sure how to achieve that.

currently all the input text in the el-inputs are bound to the same variable, and clicking to display the inputs will display them all at once.

<template>
    <div >
        <div v-for="(item, index) in items" :key="index">
            <icon @click="showTextbox"/>
            <el-input v-if="displayTextbox" v-model="textInput" />
            <el-button v-if="displayTextbox" type="primary" @click="confirm" />
            <ItemDisplay :data-id="item.id" />
        </div>
    </div>
</template>

<script>
import ItemDisplay from '@/components/ItemDisplay';

export default {
    name: 'ItemList',

    components: {
        ItemDisplay,
    },

    props: {
        items: {
            type: Array,
            required: true,
        },
    }

    data() {
        displayTextbox = false,
        textInput = '',
    },

    methods: {
        confirm() {
            // todo send request here
            this.displayTextbox = false;
        },

        showTextbox() {
            this.displayTextbox = true;
        }
    }
}
</script>

CodePudding user response:

[assuming you're using Vue2]
If you want to interact with multiple displayTextbox textInput state, you will need to have an array of objects with a specific key tied to each one of them like in this example.
As of right now, you do have only 1 state for them all, meaning that as you can see: you can toggle it for all or none only.

You'll need to refactor it with an object as in my above example to allow a case-per-case iteration on each state individually.

PS: :key="index" is not a valid solution, you should never use the index of a v-for as explained here.
PS2: please follow the conventions in terms of component naming in your template.


Also, I'm not sure how deep you were planning to go with your components since we don't know the internals of <ItemDisplay :data-id="item.id" />.
But if you also want to manage the labels for each of your inputs, you can do that with nanoid, that way you will be able to have unique UUIDs for each one of your inputs, quite useful.

CodePudding user response:

Use an array to store the values, like this:

<template>
    <div v-for="(item, index) in items" :key="index">
        <el-input v-model="textInputs[index]" />
    </div>
<template>

<script>
export default {
    props: {
        items: {
            type: Array,
            required: true,
        },
    },
    data() {
        textInputs: []
    }
}
</script>
  • Related