Vue Directive | Listen to External Dom Value Changes
Vue doesn't recognize the input change because the script is directly setting the input value at random intervals using the DOM. So, here's my solution in the form of a directive that will hook into the Element Descriptor and emit an input event so Vue will bind the new value to the form's v-model.
It can use a custom event or other element type as well.
Example (3rd Party Script):
element.value = x //Does not trigger the v-model update
Example Solution:
//Update VModel
<input
type="text"
id="x_token"
name="x_token"
v-model="form.x_token"
v-external="{descriptor: 'value'}"
/>
//Emit Event
<input
id="x_token"
type="hidden"
v-external="{descriptor: 'value', emit: 'updated'}"
@updated="..."
/>
//HTML Tag (Haven't tried this yet, but in theory...)
<div
id="data"
data-attr=""
v-external="{descriptor: 'dataset', emit: 'updated'}"
@updated="..."
/>
Solution Directive Source:
Vue.directive('external', {
bind(el, {value}) {
const {prototype} = (
el instanceof HTMLInputElement
? HTMLInputElement
: HTMLElement
)
const descriptor = Object.getOwnPropertyDescriptor(
prototype,
value.descriptor
)
Object.defineProperty(el, value.descriptor,
Object.assign({}, descriptor, {
set(val) {
const result = descriptor.set.apply(this,arguments);
el.dispatchEvent(
value.hasOwnProperty('emit')
? new CustomEvent(value.emit)
: new Event('input')
)
return result;
}
})
);
},
unbind(el, {value}) {
const {prototype} = (
el instanceof HTMLInputElement
? HTMLInputElement
: HTMLElement
)
Object.defineProperty(el, value.descriptor,
Object.getOwnPropertyDescriptor(
prototype,
value.descriptor
)
);
}
})