I have this Vue 1 component that gets an object as a prop that has to be filled by the user.
This object has this structure:
{
property1: ...,
property2: ...,
inputs: {
2130: { value: ..., comment: ... },
2131: { ... },
...,
}
}
This component is a simple modal with a table containing all necessary inputs. I'd like to check some stuff, make calculations and change styles of cells depending on user input.
When the modal loads I build the page, setting the models of those inputs with their id:
v-model="object.inputs[subgroup[1].dx.mob.id].comment"
(Note: subgroup[1] is part of another object that contains the "definition" of the table structure, by doing inputs[subgroup[1].dx.mob.id] I'm expecting to link the table field to the corresponding input of the object)
The problem is that, whatever I try, the page does not re-render. The <input> fields don't even hold the value, as soon as I click away the it disappears.
More strangely, the values are actually set, but the only way to make this component re-render and do all the nice checks and styling I need him to, is to completely recreate the component through closing and reopening the modal or by setting a v-if on a parent of the table.
These are obviously both non viable options as
- I need the page to be reactive
- Recreating the component (at each input change) takes too much time
This are the things I tried:
- Dynamically build a watcher per input
- but
vm.$watchcan't find object for some reason.
- but
...forEach((input, index)=>{
vm.$watch(`object.inputs[${index}].comment`, function(){
this.$forceUpdate();
})
}
Return inputs in a computed property and watch that
- but the page can't detect the changes
Manually launch
this.$forceUpdate()on @change and @input events- but
$forceUpdateis not a function
- but
Declare a counter in data and increment it on @change and @input events.
- but the page still does not update.
putting a
v-ifon an invisible object- but only said object gets re-rendered
changing the :key prop of my component with a data property
- but nothing happens
The only way I could do this, as anticipated, is by destroying and recreating the component.
Anyone has any solution?
Ugly Solution: After a couple more failed attempts I found something that fixes the problem even if in an improper way. Any real answer is still more than welcome.
Essentially I managed to force the component to re-render by:
- Declaring a new variable in data, I named it
key(in my case it was numeric, but any will do)- Creating an
updatefunction that switcheskeyfrom 1 to 0 and vice versa.- Binding that function to the
@blurevent of every input or select- Since my whole modal is rendered depending on a computed property, I executed a couple reading operations on
keyinside this function (In my case I assigned its value to a new variable and then logged it (not sure which of the two triggers the render, but I'd guess the first is enough))... data: function() { return { ... , key: 0 }; }, ... methods: { ... , update: function(){ this.key = this.key == 0 ? 1 : 0 } }, computed: { ... , testData: function () { //this functions builds an object that is used to render the page var data = [] var __self = this var blu = this.key // This is the line where i read key console.log(blu) this.test.inputs.forEach(function(input){ var slug = input.slug.replaceAll('#', '').split('-') __self.setItem(data, slug, input) }) console.log('data', data) return data // this value gets then passed to Object.entries() to get an iterable object I build the page with } }

