简体   繁体   中英

How to arrow toggle up and down by clicked index? Vue

How do I rotate just that arrow icon based on the clicked item?

 new Vue({ el: "#app", data() { return { isToggled: false, items: [{ id: 1, name: "Test1" }, { id: 2, name: "Test2" }, { id: 3, name: "Test3" }, { id: 4, name: "Test4" }, ] } }, methods: { arrowToggle() { this.isToggled = !this.isToggled; }, getItems() { return this.items; } }, mounted() { this.getItems(); } });
 i { border: solid black; border-width: 0 3px 3px 0; display: inline-block; padding: 3px; } .down { transform: rotate(45deg); } .up { transform: rotate(-155deg); } .accordion { display: flex; background: lightblue; align-items: center; width: 100%; width: 1000px; justify-content: space-between; height: 30px; padding: 0 20px; } .arrow { transform: rotate(-135deg); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app" style="display: flex; justify-content: center; align-items: center;"> <div v-for="(item, index) in items" :key="index"> <div class="accordion" @click="arrowToggle()"> <p> {{ item.name }}</p> <i :class="{ 'down': item.isToggled }" class="arrow"> </i> </div> </div> </div>

Based on the clicked element do I want my arrow to rotate? If i have 10 items and click on 2 items i want the icon to rotate there. Failing to bind id to the clicked item and to bind that class to rotate the item One thing is very important, I cannot set the isOpen parameter in my json ITEMS which is false which everyone recommends to me. I get it from a database and I don't have a condition for it.

You will have to toggle at individual item level. Note that I have used isToggled per item. Here is full code at: https://jsfiddle.net/kdj62myg/

Even if you get your items from DB, you can iterate through array and add a key named isToggled to each item.

HTML

<div id="app" style="display: flex; justify-content: center; align-items: center;">
        <div v-for="(item, index) in items" :key="index">
            <div class="accordion" @click="arrowToggle(item)">
               <p> {{ item.name }}</p>
                <i :class="{ 'down': item.isToggled, 'up': !item.isToggled  }"> </i>
            </div>
        </div>

 </div>

Vue

new Vue({
    el: "#app",
    data() {
        return {
            isToggled: false,
            items: [{
                    id: 1,
                    name: "Test1",
                    isToggled: false
                },
                {
                    id: 2,
                    name: "Test2",
                    isToggled: false
                },
                {
                    id: 3,
                    name: "Test3",
                    isToggled: false
                },
                {
                    id: 4,
                    name: "Test4",
                    isToggled: false
                },
            ]
        }
    },
    methods: {
        arrowToggle(item) {
            return item.isToggled = !item.isToggled;
        },
        getItems() {
            return this.items;
        }
    },
    mounted() {
        this.getItems();
    }
});

You have to map your items and attach a custom data on it to solve your problem.

Items data should be like this

  items: [{
            id: 1,
            name: "Test1",
            isToggled: false
        },
        {
            id: 2,
            name: "Test2",
            isToggled: false
        },
        {
            id: 3,
            name: "Test3",
            isToggled: false
        },
        {
            id: 4,
            name: "Test4",
            isToggled: false
        },
    ]

and your toogle function should look like this.

arrowToggle(item) {
    return item.isToggled = !item.isToggled;
},

Now, after you fetched the items from the server. You have to map it to attach a isToggled data on every item you have. like this.

getItems() {
     axios.get('api/for/items')
    .then(({data}) => {
          this.items = data.map(item => ({
                return {
                    name:item.name,
                    id:item.id,
                    isToggled:false

                }
          }))        
     });
 }

The above arrowToggle function breaks vue reactivity (google vue reactivity for docs). According to the docs, changing an object property directly will break reactivity. To keep reactivity, the function should change to:

arrowToggle(item) {
  this.$set(this.item, 'isToggled', item.isToggled = !item.isToggled)
  return item.isToggled;
},

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM