Reputation: 90
I have a component, "cmptest", which have a watched property, "needWatch". This component is inside a v-if statement, but the watched function is not called when it is rendered.
As shown in the example, the "needWatch" prop is setted with "value" data property from "cmpcheck", what makes me expect that the watch callback should be fired here.
If I remove the v-if statement, the function is called as expected when the checkbox is clicked.
<div v-if="value===true"><!--remove-->
<cmptest :need-watch="value"></cmptest>
</div><!--remove-->
Is this by design? What am I doing wrong here?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="vue.js"></script>
<script type="text/x-template" id="cmptesttemplate">
<div>
<p>needWatch: {{needWatch}}</p>
<p>updateByWatch: {{updateByWatch}}</p>
</div>
</script>
<script type="text/x-template" id="cmpchecktemplate">
<div>
<input id="checkBox" type="checkbox" value="1" v-on:click="setCheckboxValue()">
<div v-if="value===true">
<cmptest :need-watch="value"></cmptest>
</div>
</div>
</script>
</head>
<body>
<div id="container">
<cmpcheck></cmpcheck>
</div>
<script>
var cmptest = Vue.component('cmptest', {
template: '#cmptesttemplate',
data: function() {
return {
updateByWatch: ''
}
},
props: ['needWatch'],
watch: {
needWatch: function(v) {
console.log('Watched!');
this.updateByWatch = Math.random();
}
}
});
var cmpcheck = Vue.component('cmpcheck', {
template: '#cmpchecktemplate',
data: function() {
return {
value: 'Unitialized'
};
},
methods: {
setCheckboxValue: function() {
console.log('SELECTED');
var el = $(this.$el).children('#checkBox').is(':checked');
this.value = el;
}
}
});
new Vue({
el: '#container',
components: {
'cmptest': cmptest,
'cmpcheck': cmpcheck
}
});
</script>
</body>
</html>
Upvotes: 1
Views: 1046
Reputation: 601
Well, as long as value
is Unitialized
(thus, not true
), <cmptest :need-watch="value"></cmptest>
will never be rendered, so the watcher does not actually exist. Once setCheckboxValue
is called, if value
is true
, the cmptest
will be rendered and then the watcher initialized. But value
is already true
, so it's not triggered.
However, you can use:
watch: {
needWatch: {
immediate: true,
handler(nv, ov) { ... }
}
}
so that your watcher callback runs when needWatch
is initiated.
Upvotes: 1