【vue】有关watch的一道题

下面说法错误的是:

A watch监听对象必须设置deep:true

B 数组直接通过索引修改属性值,能触发watch方法

C watch内部可以写异步方法

D immediate:true可以开启首次赋值监听

这道题我做错了,选的A,正确答案是B。

先看B为什么错:

我们都知道数组直接以下标的方式修改数组项,data数据是无法响应式驱动视图的。

<body>
<div id="app">
    <h1 ref="h1" v-if="show">nowcoder</h1>
    <button @click="change" :class="arr">按钮</button>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            show: false,
            arr: ['red']
        },
        methods: {
            change() {
                this.arr[0] = 'black';
                console.log(this.arr)
            }
        },
        watch: {
            arr() {
                console.log('arr变动触发了watch更新!')
            }
        }
    })
</script>
</body>

点击按钮并没有变成黑色

此时控制台输出arr:

这个Observer代表arr数组上有一个watch监听器。

data数据改变了,但是视图没有重新渲染,watch方法也没有被触发。

换种写法:

Vue.set(this.arr, 0, 'black');

这种方式data数据会响应式更新,结果:

     

watch方法也被触发啦!以后只要记住watch方法触发与data数据响应式更新的特点一致就行了。

然后我们再看A

比如说有这么段代码:

<script>
    new Vue({
        el: '#app',
        data: {
            obj: {
                name: 'alex',
                age: 12
            }
        },
        methods: {
            changeObj() {
                this.obj.name = 'max';
            }
        },
        watch: {
            obj() {
                console.log('监听的对象发生了更新!')
            }
        }
    })
</script>

obj的name属性在视图上确实是更新了,但是watch方法可没有触发!

毕竟监听一个对象可比监听一个字符串或者数组难多了!它需要更深层次的监听。

所以此时就用到了'deep'这个属性,告诉watch要开启360度全方位无死角深层次监听,眼神牢牢锁定你!

既然要设置属性了,就不能用es6那种简写了,当然,也可以用啦,不过就不能直接在监听对象上用,可以在handler上用函数的简写。

watch: {
    obj: {
        deep: true,
        handler() {
            console.log('监听的对象发生了更新!')
        }
    }
}

然后,watch方法就可以触发啦!

最后再看D

immediate开启首次赋值监听,啥叫‘首次赋值’?其实就是data数据初始化,监听的数据初始化完成以后,就会调用watch方法了!

watch: {
    obj: {
        immediate: true,
        deep: true,
        handler() {
            console.log('首次赋值监听!')
        }
    }
}
posted @ 2021-11-20 22:10  慕斯星球  阅读(618)  评论(0)    收藏  举报