二、侦听属性
1.天气案例
在学监视属性前,首先我们来做个小案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
</div>
<script type="text/javascript">
const vm = new Vue({
el: "#root",
data: {
ishot:true
},
computed: {
info() {
// ishot ? "炎热" : "凉爽" (三元表达式,如果ishot为true,则是炎热,否则为凉爽)
return this.ishot ? "炎热" : "凉爽"
}
}
})
</script>
</body>
</html>
接下来我们再设置一个小按钮进行切换天气的状态
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<!-- 当点击这个按钮时会调用changeWeather这个函数-->
<button @click="changeWeather">切换天气</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: "#root",
data: {
ishot: true
},
computed: {
info() {
// ishot ? "炎热" : "凉爽" (三元表达式,如果ishot为true,则是炎热,否则为凉爽)
return this.ishot ? "炎热" : "凉爽"
}
},
methods: {
changeWeather() {
// 改变ishot为false
this.ishot = !this.ishot
}
}
})
</script>
</body>
</html>
点按钮后
2.天气案例_侦听属性
接下来我们就可以结合刚刚那个案例来做一个监视属性的案例,并运用配置对象watch:{} 注:{} 里要输入的是要侦听的对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: "#root",
data: {
ishot: true
},
computed: {
info() {
// ishot ? "炎热" : "凉爽" (三元表达式,如果ishot为true,则是炎热,否则为凉爽)
return this.ishot ? "炎热" : "凉爽"
}
},
methods: {
changeWeather() {
this.ishot = !this.ishot
}
},
watch:{
ishot:{
// handler什么时候调用呢? 当ishot发生改变时。
// 并且会把ishot修改前和修改后的值给你,靠参数newValue(修改后的值)和oldValue(修改前的值)
handler(newValue,oldValue){
console.log("ishot被修改了,", newValue, oldValue)
}
}
}
})
</script>
</body>
</html>
除了这种写法还有另外一种 vm.$watch 写法来监视:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: "#root",
data: {
ishot: true
},
computed: {
info() {
// ishot ? "炎热" : "凉爽" (三元表达式,如果ishot为true,则是炎热,否则为凉爽)
return this.ishot ? "炎热" : "凉爽"
}
},
methods: {
changeWeather() {
this.ishot = !this.ishot
}
},
// watch:{
// ishot:{
// // imeediate 默认为false, 初始化时让handler调用一下
// // immediate:true,
// // handler什么时候调用呢? 当ishot发生改变时。
// // 并且会把ishot修改前和修改后的值给你,靠参数newValue(修改后的值)和oldValue(修改前的值)
// handler(newValue,oldValue){
// console.log("ishot被修改了,", newValue, oldValue)
// }
// }
// }
})
vm.$watch("ishot", {
handler(newValue, oldValue) {
console.log("ishot被修改了,", newValue, oldValue)
}
})
</script>
</body>
</html>
总结:监视属性watch:
1.当被监视的属性发生变化时,回调函数会自动调用,进行相关操作。
2.监视的属性必须存在,才能进行监视!!!
3.监视两种写法:
(1)new Vue时传入watch这个配置对象
(2)通过vm.$watch监视
3.天气案例_深度监视(deep)
讲了基础的监视属性后,接下来我们开始来学习深度监视的运用,这次来监视多层级关系。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
<br>
<!-- 新设置一个容器,并用watch来监视-->
<h3>今天的温度为{{numbers.a}}</h3>
<button @click="numbers.a++">点击加1度</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: "#root",
data: {
ishot: true,
numbers: {
a: 30,
b: 20
}
},
computed: {
info() {
// ishot ? "炎热" : "凉爽" (三元表达式,如果ishot为true,则是炎热,否则为凉爽)
return this.ishot ? "炎热" : "凉爽"
}
},
methods: {
changeWeather() {
this.ishot = !this.ishot
}
},
watch: {
ishot: {
handler(newValue, oldValue) {
console.log("ishot被修改了,", newValue, oldValue)
}
},
// 监视 a 的值是否改变
a: {
handler(newValue, oldValue) {
console.log("a被修改了,", newValue, oldValue)
}
}
}
})
</script>
</body>
</html>
由于a再numbers内层,那会不会是watch要检测的值有问题呢?那我们将a改为numbers后再看看
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
<br>
<!-- 新设置一个容器,并用watch来监视-->
<h3>今天的温度为{{numbers.a}}</h3>
<button @click="numbers.a++">点击加1度</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: "#root",
data: {
ishot: true,
numbers: {
a: 30,
b: 20
}
},
computed: {
info() {
// ishot ? "炎热" : "凉爽" (三元表达式,如果ishot为true,则是炎热,否则为凉爽)
return this.ishot ? "炎热" : "凉爽"
}
},
methods: {
changeWeather() {
this.ishot = !this.ishot
}
},
watch: {
ishot: {
handler(newValue, oldValue) {
console.log("ishot被修改了,", newValue, oldValue)
}
},
// 监视 a 的值是否改变
numbers: {
handler(newValue, oldValue) {
console.log("a被修改了,", newValue, oldValue)
}
}
}
})
</script>
</body>
</html>
这个时候就要使用 deep 这个配置项就可以搞定了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
<br>
<!-- 新设置一个容器,并用watch来监视-->
<h3>今天的温度为{{numbers.a}}</h3>
<button @click="numbers.a++">点击加1度</button>
<h3>今天这个温度有{{numbers.b}}人出门</h3>
<button @click="numbers.b++">点击加1度</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: "#root",
data: {
ishot: true,
numbers: {
a: 30,
b: 20
}
},
computed: {
info() {
// ishot ? "炎热" : "凉爽" (三元表达式,如果ishot为true,则是炎热,否则为凉爽)
return this.ishot ? "炎热" : "凉爽"
}
},
methods: {
changeWeather() {
this.ishot = !this.ishot
}
},
watch: {
ishot: {
handler(newValue, oldValue) {
console.log("ishot被修改了,", newValue, oldValue)
}
},
numbers: {
// 监视多级结构中所有属性的变化
deep:true,
handler(newValue, oldValue) {
console.log("numbers被修改了,", newValue, oldValue)
}
}
}
})
</script>
</body>
</html>
如若我只想监视numbers下a或者b,则可以用 "numbers.a":{}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
</head>
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
<br>
<!-- 新设置一个容器,并用watch来监视-->
<h3>今天的温度为{{numbers.a}}</h3>
<button @click="numbers.a++">点击加1度</button>
<h3>今天这个温度有{{numbers.b}}人出门</h3>
<button @click="numbers.b++">点击加1度</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: "#root",
data: {
ishot: true,
numbers: {
a: 30,
b: 20
}
},
computed: {
info() {
// ishot ? "炎热" : "凉爽" (三元表达式,如果ishot为true,则是炎热,否则为凉爽)
return this.ishot ? "炎热" : "凉爽"
}
},
methods: {
changeWeather() {
this.ishot = !this.ishot
}
},
watch: {
ishot: {
handler(newValue, oldValue) {
console.log("ishot被修改了,", newValue, oldValue)
}
},
// 监视多级结构中某个属性的变化
"numbers.a": {
handler(newValue, oldValue) {
console.log("a被修改了,", newValue, oldValue)
}
}
}
})
</script>
</body>
</html>
总结:
1.Vue中的watch默认不监视内部值的改变(一层)
2.配置deep:true可以监视对象内部值改变(多层)
备注:
(1)Vue自身可以检测对象内部值的改变(“numbers.a”:{}),而Vue提供的watch默认不可以
(2)使用watch时根据数据的具体结构,决定是否采用采用深度监视