Home > Net >  vuetify: how to make v-data-table row blink when item values are updated
vuetify: how to make v-data-table row blink when item values are updated

Time:06-27

I would like to create a table that when items is updated, the row blink once.

i managed to make a row blink when the component starts, but it does not blink when value is updated.

i created an example with two css class (only for test), one that blinks once and another that blinks infinite.

if we update items values, we can see that the infinite still blinks and change rows as the condition is filled, but the items that should blink once, didn't change.

any help will be appreciated.

Vue.config.productionTip = false;
Vue.config.devtools = false;

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data() {
    return {
      items: [{
          id: 1,
          name: 'Frozen Yogurt',
          calories: 159,
        },
        {
          id: 2,
          name: 'Ice cream sandwich',
          calories: 237,
        },
        {
          id: 3,
          name: 'Eclair',
          calories: 262,
        },
        {
          id: 4,
          name: 'Cupcake',
          calories: 305,
        },
      ],
      headers: [{
          text: 'Dessert',
          value: 'name',
        },
        {
          text: 'Calories',
          value: 'calories'
        },
      ],
    };
  },
  methods: {
    blink(item) {
      if (item.calories > 200){
        return 'blink-great';
      } else {
        return 'blink-less';
      }
    },
    getRandomInt(min, max) {
      min = Math.ceil(min);
      max = Math.floor(max);
      return Math.floor(Math.random() * (max - min))   min;
    },
    updateValues() {
      const newValues = this.items.map((el) => { 
        return {...el, calories: this.getRandomInt(100,500)}; 
      })
      this.items = newValues
    } 
  },
  computed: {
    displayItems() {
      var newItems = this.items.map((el) => { 
        return {...el, calories: el.calories * 1}; 
      })
      return newItems
    }
  },
});
.blink-less {
  animation: blinking ease-out 1s 3;
  --background-color: #FF0000
}

.blink-great {
  animation: blinking ease-out 1s infinite;
  --background-color: #0000FF
}

@keyframes blinking {
  0% {
    background-color: var(--background-color);
  }
  100% {
    background-color: #fff;
  }
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>

<div id="app">
  <v-app>
    <v-container>
      <v-row >
        <v-btn 
          @click="updateValues()"
        > Update value </v-btn>
      </v-row>
      <v-row >
        <v-data-table 
         hide-default-footer 
         :headers="headers" 
         :items="displayItems" 
         :item-
       />
      </v-row>
    </v-container>
  </v-app>
</div>

CodePudding user response:

I created a flag and added new css classes.. it works but has poor code. If i found a better and clean solution i post it here

Vue.config.productionTip = false;
Vue.config.devtools = false;

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data() {
    return {
      controlAnimation: false,
      items: [{
          id: 1,
          name: 'Frozen Yogurt',
          calories: 159,
        },
        {
          id: 2,
          name: 'Ice cream sandwich',
          calories: 237,
        },
        {
          id: 3,
          name: 'Eclair',
          calories: 262,
        },
        {
          id: 4,
          name: 'Cupcake',
          calories: 305,
        },
      ],
      headers: [{
          text: 'Dessert',
          value: 'name',
        },
        {
          text: 'Calories',
          value: 'calories'
        },
      ],
    };
  },
  
  methods: {
    blink(item) {
      if (this.controlAnimation) {
        let itemClassTrue = 'blink-even-true'
        /* check item.value, based on condition...
        itemClassTrue = 'blink-less-true'
        itemClassTrue = 'blink-even-true'
        itemClassTrue = 'blink-great-true'
        */
        return itemClassTrue;
      } else {
        let itemClassFalse = 'blink-great-false'
        /* check  item.value, based on condition...
        itemClassTrue = 'blink-less-false'
        itemClassTrue = 'blink-even-false'
        itemClassTrue = 'blink-great-false'
        */
        return itemClassFalse;
      }
    },
    getRandomInt(min, max) {
      min = Math.ceil(min);
      max = Math.floor(max);
      return Math.floor(Math.random() * (max - min))   min;
    },
    updateValues() {
      const newValues = this.items.map((el) => { 
        return {...el, calories: this.getRandomInt(100,500)}; 
      })
      this.items = newValues
    } 
  },
  computed: {
    displayItems() {
      this.controlAnimation = !this.controlAnimation
      var newItems = this.items.map((el) => { 
        return {...el, calories: el.calories * 1}; 
      })
      return newItems
    }
  },
});
.blink-less-true {
  animation: blinking-less-true 1s 2 !important;
  --background-color: rgb(196, 76, 76) !important;
}

.blink-even-true {
  animation: blinking-even-true 1s 2 !important;
  --background-color: #fa0 !important;
}

.blink-great-true {
  animation: blinking-great-true 1s 2 !important;
  --background-color: rgb(3, 163, 70) !important;
}

.blink-less-false {
  animation: blinking-less-false 1s 2 !important;
  --background-color: rgb(196, 76, 76) !important;
}

.blink-even-false {
  animation: blinking-even-false 1s 2 !important;
  --background-color: #fa0 !important;
}

.blink-great-false {
  animation: blinking-great-false 1s 2 !important;
  --background-color: rgb(3, 163, 70) !important;
}

@keyframes blinking-less-false {
  0% { background-color: var(--background-color); }
  100% { background-color: #fff; }
}

@keyframes blinking-even-false {
  0% { background-color: var(--background-color); }
  100% { background-color: #fff; }
}

@keyframes blinking-great-false {
  0% { background-color: var(--background-color); }
  100% { background-color: #fff; }
}

@keyframes blinking-less-true {
  0% { background-color: var(--background-color); }
  100% { background-color: #fff; }
}

@keyframes blinking-even-true {
  0% { background-color: var(--background-color); }
  100% { background-color: #fff; }
}
@keyframes blinking-less-true {
  0% { background-color: var(--background-color); }
  100% { background-color: #fff; }
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>

<div id="app">
  <v-app>
    <v-container>
      <v-row >
        <v-btn 
          @click="updateValues()"
        > Update value </v-btn>
      </v-row>
      <v-row >
        <v-data-table 
         hide-default-footer 
         :headers="headers" 
         :items="displayItems" 
         :item-
       />
      </v-row>
    </v-container>
  </v-app>
</div>

  • Related