Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue does not detect changes when undefined property is added by external library

Tags:

vue.js

vuejs2

I am trying to make a form renderer, but have problems getting the form-content update properly. I created a sandbox with a minimal version: https://codesandbox.io/s/23z4y1n9kp

The problem

The form has three fields: a, b and c. It is initialised with a value for a and one for b, but not for c. When I update the values for a or b, I see the form content update as well and in the console I see the setter method is called with the correct value. However, when I fill in a value for c, nothing seems to happen in the page, but the console indicates that the setter was called correctly. This means the document object got updated correctly, but Vue does not know it.

An external library calls the setter

I understand Vue cannot watch undefined properties or detect new properties (https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats). You should do Vue.set to make Vue watch them. However, in this case this is not possible because I use an external library that does the actual setting of the value: docmod.

I’ve included a minimal version of the library in the sandbox to give you an idea of what it does. It is this library that adds the value of the fields to the document object. It uses specific getters and setters to do this, I want to keep those getters and setters to make sure the docmod keeps working as expected.

Things I cannot do

  • Define c by setting documentContent: { value: { a: '1', b: 'foo', c: '' }}. It is not known in advance what properties will be present
  • Alter the docmod library to put Vue.set in there

Possible solutions

Is there a way I can make Vue watch the full document object and detect changes in fields that did not have an initial value? Suppose, the docmod can notify me something changed, can I force Vue to update its page in some way? Can I redefine the object properties of the value to wrap the original getters and setters with some code that calls Vue.set?

Any help is greatly appreciated!

like image 224
NeleR Avatar asked Aug 30 '25 18:08

NeleR


1 Answers

You can call this.$forceUpdate(); to force Vue to update the screen. This is not recommended way of doing things, but in your case I can't really see any other.

See updated version here: https://codesandbox.io/s/zk4vy6qly3

I have added a method refresh in your Form.vue, which is bound to @input for your text box. This method calls this.$forceUpdate(); to cause Vue to rerender.

like image 64
Archeg Avatar answered Sep 02 '25 22:09

Archeg