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
How to Shuffle the Characters in a String in JavaScript
Date.Setmonth' Causes the Month to Be Set Too High If 'Date' Is at the End of the Month
How to Replace Captured Groups Only
JavaScript .Replace Command Replace Page Text
Es6: Conditional & Dynamic Import Statements
Regex for Match/Replacing JavaScript Comments (Both Multiline and Inline)
Access-Control-Allow-Origin Denied Spotify API
Why Use Object.Prototype.Hasownproperty.Call(Myobj, Prop) Instead of Myobj.Hasownproperty(Prop)
Check If Option Is Selected with Jquery, If Not Select a Default
Inject a Script Tag with Remote Src and Wait for It to Execute
How to Do a Deep Comparison Between 2 Objects with Lodash
How to Set a Js Object Property Name from a Variable
How to Set the Prototype of a JavaScript Object That Has Already Been Instantiated
How to Check Whether <Ng-Content> Is Empty? (In Angular 2+ Till Now)