udpate #2: It is not a bug, it was my own fault. I extended the BaseComponent by a extend() method as well as putting extends: BaseComponent into the options. I thought I needed both, but extends: BaseComponent in the options seems to be enough.
So the double “extend” has apparently duplicated the watcher which lead to the strange behavior I documented in my question.
update: I found out what causes this problem: The watcher seems to be duplicated, because it’s in a BaseComponent which is extended by the Component which is used in my example.
so export default BaseComponent.extend({ name: ‘Component’, …}) seems to duplicate the watch object instead of “merging” it - there is now one in the BaseComponent (where it is implemented initially) and one in the Component - and of course both react to prop-updates.
This seems to be a bug IMHO.
Using vue-cli with single file components.
when setting a prop in one component via a method:
<template>
<div>
<other-component :my-object=”myObject” />
</div>
</template>
<script>
export default (vue.js as VueConstructor).extend({
data() {
return {
myObject: null
}
},
methods: {
actionButtonClicked(action, ID) {
console.log(‘actionButtonClicked’);
this.myObject = {
action: action,
ID: ID
}
}
}
});
</script>
then when watching the prop in the other component with a watcher - but watch gets called twice on every execution of the method.
<script>
export default (vue.js as VueConstructor<Vue>).extend({
/* … */
props: {
myObject: {
type: Object,
default: null
},
watch: {
‘myObject.ID’(value, oldValue) {
console.log(‘watcher executed’);
}
}
/* … */
});
</script>
so in the console i get the output:
actionButtonClicked
watcher executed
watcher executed
.. every time the method gets called.
I already tried all different variants of watchers - for example with deep: true + handler. but this all didn’t change anything about the watcher being called twice.
Solution :
My watcher was duplicated because I was extending my BaseComponent in two ways:
by the extend() method of the component itself
by putting extends: BaseComponent into the options of the “outer” component
I thought you needed to use both pieces of code to extend another component, but apparently this is wrong and can lead to bad side effects.