Search code examples
typescriptvue.jselectronvue-component

How to set different style to only one element generated dynamically in Vue


I d like to have one "active" tab after clicking on it. I cant find the way how to do it. The only thing i could think of, was to change style after clicking on it, but the problem is that the style wont go back to normal after clicking on another tab. I also tried to have a list of created tabs with property active but in this case i am not able to change style of element from methods function.

I am dynamically creating tabs in here:

<template>
  <div class="navbar">
    <div class="list_pages">
      <New_page v-for="index in page_counter" :key="index" :new_p="false" @click="loging(index)" :index="index" :list="page_arr"/>
    </div>
  </div>
</template>

This is file for <New_page>:

<template>
  <div class="pad">
    <div class="card" @click="change_style()" :style="{
        backgroundColor: chng_border ? 'red' : '#5fc9f3'
      }" v-if="!new_p">
      <p>{{index}}</p>
    </div>
</template>
<script>
export default {
  data() {
    return {
      chng_border : false
    }
  },
  props: ['p_c', 'new_p', 'index', 'clicked', 'list'],
  methods: {
    change_style() {
      this.chng_border = !this.chng_border
    }
  }
}
</script>

I cant go back to normal state after clicking on another element


Solution

  • How about storing active_index in your parent component and pass it to your New_page

    eg:

    <template>
      <div class="navbar">
        <div class="list_pages">
          <New_page v-for="index in page_counter" :key="index" :index="index" :is_active="is_active(index)" @clicked="foo"/>
        </div>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          active_index: 0
        }
      },
      methods: {
        is_active(index) {
          return index === this.active_index
        },
        foo(index) {
          this.active_index = index
        }
      }
    }
    </script>
    

    In the NewPage file you can emit event to change active index in the parent component eg:

    <template>
      <div class="pad">
        <div class="card" @click="change_style()" :style="{
            backgroundColor: is_active ? 'red' : '#5fc9f3'
          }" v-if="!new_p">
          <p>{{index}}</p>
        </div>
    </template>
    
    <script>
    export default {
      props: ['index', 'is_active'],
      emits: ['clicked'],
      methods: {
        change_style() {
          this.$emit('clicked', this.index)
        }
      }
    }
    </script>