Can You Force Vue.Js to Reload/Re-Render

Can you force Vue.js to reload/re-render?

Try this magic spell:

vm.$forceUpdate();
//or in file components
this.$forceUpdate();

No need to create any hanging vars :)

Update: I found this solution when I only started working with VueJS. However further exploration proved this approach as a crutch. As far as I recall, in a while I got rid of it simply putting all the properties that failed to refresh automatically (mostly nested ones) into computed properties.

More info here: https://v2.vuejs.org/v2/guide/computed.html

VueJs force component to reload

Setting an existing Object prop is actually reactive, and so is adding a new object to an array prop. In your example, getData() would cause compare-value to re-render without having to call reloadComponent() (demo).

I read that VueJs can not detect a change in an Object.

You're probably referring to Vue 2's change-detection caveats for objects, which calls out addition or deletion of properties on the object.

Caveat example:

export default {
data: () => ({
myObj: {
foo: 1
}
}),
mounted() {
this.myObj.foo = 2 // reactive
delete this.myObj.foo // deletion NOT reactive
this.myObj.bar = 2 // addition NOT reactive
}
}

But Vue provides a workaround, using Vue.set() (also vm.$set()) to add a new property or Vue.delete() (also vm.$delete()) to delete a property:

export default {
//...
mounted() {
this.$delete(this.myObj, 'foo') // reactive
this.$set(this.myObj, 'bar', 2) // reactive
}
}

How to force rerender of one Vue component from another

I think that you need to RELOAD the basket items on new item added, IF you need the 'roundtrip with the server (send the new item to the server, some calcs, back to front-end with the cart updated)'.
So: put in a separate method the basket load, call it from the mounted and again on the basket-updated event:
This is the shortest answer:

LoadBasket() {
fetch('http://localhost:3000/api/basket')
.then(res => res.json())
.then(data => this.items = data)
.then(items => this.calcTotal(items));
}

mounted(){
//The first time:
this.LoadBasket();

eventBus.$on('basket-updated', (data) => {
if(data){
//on basket updated
this.LoadBasket();
}
});
}

Remember that the Data is a 'reactive' property: if it change then also the presentation will be updated (if needed, tnx to the virtual dom used in VueJS): there is no need to call a 'refresh UI' method.

By the way, if you need only to add the just created item to the Items list you need only to push it into the array:

this.Items.push(newItem);

PS: I recommend you to take a look on Vuex (https://vuex.vuejs.org/guide/state.html) for the state management of your application: it's little bit more complex but permit a better design of your application.

How can I force the nested component to rerender

You had not any updates on front-end part (inside vue)
You need to do something like this:

endDrag: function (event) {
let column = event.to.parentElement.parentElement
$.ajax({
url: '/tasks/change-status',
type: 'POST',
data: {'task_id': event.item.id, 'status': column.id},
success: function (data) {
if (data.success) {

const task = this.tasks.find(t => t.id === event.item.id);
task.status = column.id;

Toastify({
text: "Task status has been successfully updated!",
duration: 3000,
destination: base_url + '/tasks' + "show/" + event.item.id,
newWindow: true,
close: true,
className: 'custom-toast',
gravity: "top", // `top` or `bottom`
position: "center", // `left`, `center` or `right`
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
stopOnFocus: true, // Prevents dismissing of toast on hover
onClick: function () {
} // Callback after click
}).showToast();

}
}
});
}

So find the task to update:

const task = this.tasks.find(t => t.id === event.item.id);

And update it with you status

task.status = column.id;

Cleanest way to re-render component in Vue

The cleanest way is to have the disabled state somewhere where you can reset it, because re-rendering your component to reset it is making use of a side-effect of destroying and re-creating your components. It makes it hard for someone to figure out why the buttons are enabled again, because there is no code changing the disabled variable to false anywhere that is being called when you rerender.

That said, you see your current behaviour because Vue aggregates all changes of the current "tick", and only rerenders at the end of that tick. That means if you set your variable to false, then to true, it will only use the last value.

// Nothing happens
this.showSomething = false
this.showSomething = true

To force it to re-render, you can use the trick Amitha shows, using key. Since Vue will use an instance per key value, changing the key will destroy the old one and create a new one. Alternatively, you can use this.$nextTick(() => { ... }) to force some of your code to run on the next tick.

// Destroy all the things
this.showSomething = false
this.$nextTick(() => {
// Okay, now that everything is destroyed, lets build it up again
this.showSomething = true
});

What is correct way to re-render one component from another [Vue.js]

@Lube this is the best way to force a re-render of a component. I've needed to do the same for graph components in the past when my data changes.

There's a great article I've linked to below that explains the various ways of forcing a re-render, but ultimately the best way is adding a :key property to your component and updating that key whenever you need a re-render.

Article can be found here.

Vue.js force re-render of component which contains v-once directive

This use case can be resolved by surrounding the v-once component in a container, and then triggering component re-render.

I was able to trigger the component re-render by using :key="$route.params.id" on the component in question from within the container.

i.e.

<div id="container-component">
<custom-component :key="$route.params.id"></custom-component>
</div>


Related Topics



Leave a reply



Submit