未调用 v-if 语句中组件的已监视 prop 回调

Watched prop callback of a component inside a v-if statement is not called

我有一个组件 "cmptest",它有一个监视 属性、"needWatch"。 此组件在 v-if 语句中,但在呈现时未调用监视函数。

如示例所示,"needWatch" 道具设置了来自 "cmpcheck" 的 "value" 数据 属性,这让我期望手表回调应该被触发这里。

如果我删除 v-if 语句,则在单击复选框时会按预期调用该函数。

<div v-if="value===true"><!--remove-->
    <cmptest :need-watch="value"></cmptest>
</div><!--remove-->

这是设计使然吗?我在这里做错了什么?

<!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>

好吧,只要 valueUnitialized(因此,不是 true),<cmptest :need-watch="value"></cmptest> 就永远不会被渲染,所以 watcher 实际上并不存在。一旦 setCheckboxValue 被调用,如果 valuetrue,那么 cmptest 将被渲染,然后 watcher 被初始化。但是value已经是true,所以没有触发。

但是,您可以使用:

watch: {
  needWatch: {
    immediate: true,
    handler(nv, ov) { ... }
  }
}

以便您的观察者回调在 needWatch 启动时运行。