I have a v-data-table. On a pop up, I select a few of the columns of the table and combine these values and add them back to the table as a new column.
My problem is, I can't re-render the v-data-table after I clicked my Save button. I tried $forceUpdate but didn't work. What can i use?
It's pretty weird it doesn't get rerendered automatically. But one solution could be to assign your data an empty array (I assume it's an array) and right after it put:
tabledata = []; // empty your data here
Vue.nextTick(function () {
tabledata = [0,1,2]; // assign your new data here
})
https://v2.vuejs.org/v2/api/#Vue-nextTick
Related
Despite I'am using refresh method, my doesn't get updated after I change some element of its items[] records:
I have to add a dummy/ghost record and then delete it to get the record I want updated:
this.items[this.posItemEdited] = element;
//this.$refs['theTable'].refresh(); //Doesn't work
//this.$root.$emit('bv::refresh::table', 'theTable'); //Doesn't work
//TRICK: add and delete
this.items.push(element);
this.items.splice(this.items.length - 1, 1);
Below code does not work because of caveats in a reactivity of Vue.js
this.items[this.posItemEdited] = element;
See Reactivity for arrays
To solve this problem you need to use $set:
this.$set(this.items, this.posItemEdited, element)
I'm currently using Bootstrap Vue's b-table to display my data from the database. I have SignalR implemented, where it will automatically update/refresh the table with the new data received from the server.
I would like to add some sort of highlight css styling or row variant
when new data gets populated into the table, and then remove the styling from the row on mouseover/hover. Currently, I can receive events in the console when a row gets hovered.
How am I able to achieve this functionality using Vue.js?
b-table
<b-table
...
:items="items"
:fields="fields"
#row-hovered="myRowHoverHandler"
...
> ... </b-table>
script tag
props: {
...
items: Array,
...
}
methods: {
myRowHoverHandler(record, index) {
console.log(this.items[index].id);
},
...
}
When the item gets updated, you can simply set the _rowVariant on the item that got updated, and then on hover remove it from the item again as shown in the codepen below.
Remember to use $set and $delete to keep Vue's Reactivity happy
https://codepen.io/Hiws/pen/WqKqdG
I am using V-data-table along with vuex store. Below are the points how I configured my v-data-table
Disabled sort on each column
bind the v-data-table items with vuex state store data
using sortablejs to drag and drop the rows
Problem:
When I drag and drop the rows in the v-data-table the I am updating the vuex store(updating the index value on the objects in array with the table row index value). Vuex is updating properly but the data rendered in the v-data-table is not in the order as they are in the vuex state store
Could someone help me on this
The best way I tried to overcome this problem is to force re-render the v-data-table component, but when I do this I cannot drag and drop anymore
Force rendered using the following the template
<template>
<component-to-re-render :key="componentKey" />
</template>
// script
export default {
data() {
return {
componentKey: 0,
};
},
methods: {
forceRerender() {
this.componentKey += 1;
}
}
}
This might not be the optimal solution, but I had a similar problem except I was just using a regular Array. I managed to fix it by calling the Sortable.create() method in updated() life cycle hook.
My guess is that when you call Sortable.create(table, ...) it refers to that instance of the table element. However, when you try to change the table by modifying the key, it changes that instance. Therefore, you need to call Sortable.create() again whenever the vue component is updated.
I have two components in mu app.vue and i will send data from app.vue to my first component(filter component) at the time of page load.
Now based on the user actions in the displayed data in the second component i need to pass new vales back to the first component.
There i am using a and a . Consider one of the props i receive in the first component is "nselectedOption" and i do this in data: { return { selectedOption: this.nselectedOption }} to avoid mutation warning.
Now everytime i update the values for this component from second component, i am seeing changes in "nselectedOption" only and not in "selectedOption". Can you explain why is that ?
I need the updated value into a v-model of .
1. If i use "nselectedOption" it is updating the textbox but while editing the value throws error.
2. If i use "selectedOption" it is not updating the values in the textbox itself.
I have even tried using the computed values to return the value, it works but if i try to change values in other options in the filter component the already updated values displays null or nothing.
Please help me. Is this problem can be solved using State Management Concept or do i have to have a separate compoenent other than App.Vue to do all this so that it would act as a parent/child kinda thing or is there anyother way to overcome this.
Try using watcher. If you watch for nselectedOption, everytime it changes, the watcher will fire and bind the changed value to selectedOption.
props: ['nselectedOption'],
data: {
selectedOption
},
watch: {
nselectedOption: function (val) {
this.selectedOption = val
}
}
Also, if the prop you are watching is an object/array, consider using spread operator if you want to make a local copy to avoid mutation.
this.someObj = { ...someProp }
I have a template in Vue.js that looks like this:
<div class="filter">
<div class="checkbox" v-for="(value, index) in range" :key="index">
<span class="hotels">{{ count(index) }}</span>
</div><!-- /.checkbox -->
</div><<!-- /.filter -->
The count method is important here. It triggers twice and also seems to be the cause of the second trigger and re-render.
This is my method:
count(value) {
console.log('count');
// Get the filtered AJAX data.
let hotels = this.allHotels;
const filters = Object.entries(this.filters);
for (let i = 0; i < filters.length; i += 1) {
// Get the Object from the array(index 0 being the name).
const filter = filters[i][1];
// Break the v-model reference by creating a shallow copy.
const values = filter.values.slice(0);
// Merge any selected checkbox values with the one we are currently iterating.
if (!values.includes(value)) values.push(Number(value));
// Check if the current filter has selected checkboxes and filter if it does.
hotels = filter.function(hotels, values);
}
return hotels.length;
}
Whenever I everything except the console.log() it works fine. Whenever I leave in the rest of the code the entire template seems to re-trigger. This seems strange because I am leaving the data in the template and the computed properties that the template relies on alone.
Is there any way to debug what is causing the second re-render?
Entire component:
https://gist.github.com/stephan-v/a5fd0b6bae854276666536da445bbf86
Edit
My components count function has a computed property in it called allHotels. This property is being set as a prop.
On the very first console.log it seems empty and then straight away it will get set causing the re-render. I was hoping that because this prop is coming from the backend it would take it as the initial value but this is not the case.
Is there anything to overcome this and prevent a re-render? There is no need for a re-render if Vue would take the prop data from the backend as initial data straight away.
Hopefully it is clear what I mean by this.
Replication:
Somehow I can't seem to replicate this, I would expect this to also work like my code and show an empty title on the first pass with a console.log:
https://jsfiddle.net/cckLd9te/123/
Perhaps because my prop data that I am passing into my component is a pretty big json_encoded block it takes time for Vue.js to interpret the data?