话不多说,直接上代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="computed_props">
千米 : <input type="text" v-model="kilometers"> 米 : <input type="text" v-model="meters">
</div>
<p id="info"></p>
<script type="text/javascript">
var vm = new Vue({
el: '#computed_props',
data: {
kilometers: 0,
meters: 0
},
methods: {},
computed: {},
watch: {
kilometers: function(newValue, oldValue) {
console.log('kilometers newValue:' + newValue + ', oldValue:' + oldValue)
this.kilometers = newValue;
this.meters = this.kilometers * 1000
},
meters: function(newValue, oldValue) {
console.log('meters newValue:' + newValue + ', oldValue:' + oldValue)
this.kilometers = newValue / 1000;
this.meters = newValue;
}
}
});
// $watch 是一个实例方法
vm.$watch('kilometers', function(newValue, oldValue) {
console.log('实例方法')
// 这个回调将在 vm.kilometers 改变后调用
document.getElementById("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
})
</script>
</body>
</html>
上面是第一段代码,在控制台打印如下:
kilometers newValue:1, oldValue:0
meters newValue:1000, oldValue:0
kilometers newValue:1, oldValue:1
实例方法
这里不太理解为什么“实例方法”只打印了一次,是不是watch监听的两种实现方式有区别?
第二段代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="computed_props">
千米 : <input type="text" v-model="kilometers"> 米 : <input type="text" v-model="meters">
</div>
<p id="info"></p>
<script type="text/javascript">
var vm = new Vue({
el: '#computed_props',
data: {
kilometers: 0,
meters: 0
},
methods: {},
computed: {},
watch: {
kilometers: function(newValue, oldValue) {
console.log('kilometers newValue:' + newValue + ', oldValue:' + oldValue)
},
meters: function(newValue, oldValue) {
console.log('meters newValue:' + newValue + ', oldValue:' + oldValue)
this.kilometers = newValue / 1000;
this.meters = newValue;
}
}
});
// $watch 是一个实例方法
vm.$watch('kilometers', function(newValue, oldValue) {
this.kilometers = newValue;
this.meters = this.kilometers * 1000
console.log('实例方法')
// 这个回调将在 vm.kilometers 改变后调用
document.getElementById("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
})
</script>
</body>
</html>
控制台打印如下
kilometers newValue:1, oldValue:0
实例方法
meters newValue:1000, oldValue:0
kilometers newValue:1, oldValue:1
实例方法
“实例方法”被打印了两次
我个人的理解是两种watch的实现方式应该没啥区别,我看官网的文档也没有详细的说明,但是这个例子看来,这两者还是有区别的,有没有大神能给解惑的?
===============================更新=======================
不会引起死循环,有疑问的可以把代码自己考下来运行一遍就清楚了
https://github.com/vuejs/vue/blob/dev/src/core/instance/state.js#L303
从源码上看是没有区别的,最终调用了同一块的代码。第一块代码中,可能你对kilometers 重新赋值后,下面那个watcher被移除了队列,所以没有执行到(具体要看看源码)