0
点赞
收藏
分享

微信扫一扫

18.Vue的监视属性

灯火南山 2022-08-23 阅读 45


目录

​​1.天气案例引入​​

​​2.计算属性实现案例回顾​​

​​2.1 需要注意的坑​​

​​2.2 实现小技巧​​

​​3.监视属性​​

​​3.1 watch配置的监视​​

​​3.2 计算属性是否可监视?​​

​​3.3 除watch配置之外的另一种监视办法​​

​​3.4 两种监视方式的用法​​

​​4.总结​​

1.天气案例引入

今天我们来讲一下Vue的监视属性。还是通过一个小案例来引入。

我们需要实现的案例功能是在页面上输出今天天气很凉爽/炎热,而天气的状态可以通过按钮来切换。而且在切换的同时在控制台输出:天气变化了,现在是:凉爽,原来是:炎热。可以看到之前和之后的状态。

我们先来简单实现一下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很{{isHot ? '炎热' : '凉爽'}}</h2>
<button>切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
new Vue({
el:'#root',
data:{
isHot:true
}
})
</script>
</html>

 实现效果:

18.Vue的监视属性_vue.js

我们可以看到简单的界面效果出来了。那可不可以实现切换呢?我们可以用Vue的开发者工具试验一下。

18.Vue的监视属性_vue.js_02

说明切换是可以起作用的。

2.计算属性实现案例回顾

但是我们可以看到 {{isHot ? '炎热' : '凉爽'}} 这样的表达式又写的过于麻烦了,既然我们上一节学了计算属性,那我们这里就用计算属性来实现一下。顺便给按钮也绑定切换事件。

由于天气是否炎热或者凉爽,我们只需要计算出来给别人看就行,所以我们这里在写的时候就可以用计算属性的简写形式。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click = "changeWeather">切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
new Vue({
el:'#root',
data:{
isHot:true
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{
changeWeather(){
this.isHot = !this.isHot
}
}
})
</script>
</html>

实现效果:

18.Vue的监视属性_javascript_03

 到这里我们这个小案例就讲完了,但是这个小案例特别适合讲两个东西,一个是坑,一个是技巧。

2.1 需要注意的坑

先说坑,Vue的开发者工具有个缺点,如果用到的元素在页面上不存在,即使元素值改变了,在工具中也不会体现,因为Vue的开发者工具认为,既然你都没用到这个值,就算你变化了,我也没必要给你展示变化。

我们下面可以试试将模板中的info去掉,然后再点击切换,看看是不是这么回事。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很</h2>
<button @click = "changeWeather">切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
const vm = new Vue({
el:'#root',
data:{
isHot:true
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{
changeWeather(){
this.isHot = !this.isHot
}
}
})
</script>
</html>

实现效果:

18.Vue的监视属性_javascript_04

我们可以看到实际上数据已经改了,但是因为元素并没有在页面上用到,所以Vue的开发者工具中并没有实时更新。

2.2 实现小技巧

在刚才的按钮切换实现方法中我们可以看到,我们为了实现点击切换,写了@Click,写了methods,又写了changeWeather方法,最终其实只是为了实现一句话this.isHot = !this.isHot,那么如果是像这样的情况,我们可以把方法写的更加简单一点。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click = "isHot = !isHot">切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
const vm = new Vue({
el:'#root',
data:{
isHot:true
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{

}
})
</script>
</html>

实现效果:

18.Vue的监视属性_vue.js_05

我们可以看到直接把方法中的内容写到@click后面也可以实现同样的效果。理论上来说,即使有很多行语句也可以通过分号分隔的方式这样去写。比如下面这样。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}},{{x}}</h2>
<button @click = "isHot = !isHot;x++">切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
const vm = new Vue({
el:'#root',
data:{
isHot:true,
x:1
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{

}
})
</script>
</html>

实现效果:

18.Vue的监视属性_javascript_06

但是有一种情况是例外的,比如alert语句是不能用这种写法的,我们直接用就会报错。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}},{{x}}</h2>
<button @click = "alert(1)">切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
const vm = new Vue({
el:'#root',
data:{
isHot:true,
x:1
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{

}
})
</script>
</html>

18.Vue的监视属性_javascript_07

这是因为alert并不存在于vm身上,而是在外部的window身上。如果我们想这样用的话,可以先把window挂到vm身上,然后再通过window调用alert即可。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}},{{x}}</h2>
<button @click = "window.alert(1)">切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
const vm = new Vue({
el:'#root',
data:{
isHot:true,
x:1,
window

},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{

}
})
</script>
</html>

18.Vue的监视属性_vue.js_08

3.监视属性

接下来我们就把刚才的天气案例,用监视属性去写一下。

监视属性,顾名思义,其实就是监视某一个属性的变化。

刚刚我们之所以能够实现天气的切换,是因为我们不断的在修改isHot的值,接下来我们就监测一下isHot的改变。只要isHot变了,我们就要收到通知。

3.1 watch配置的监视

在Vue中,如果想要实现监视,我们就要用到一个全新的配置项watch。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click = "changeWeather">切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
const vm = new Vue({
el:'#root',
data:{
isHot:true

},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
isHot:{
//handler什么时候调用?当isHot发生改变时
handler(){
console.log('isHot被修改了')
}
}
}
})
</script>
</html>

18.Vue的监视属性_vue.js_09

我们可以看到当isHot属性被修改的时候是可以即使收到通知的。其实watch不仅能告诉我们它的值被修改了,其实还可以通过参数的方式告诉我们修改前和修改后的值是多少。

18.Vue的监视属性_javascript_10

在watch中不仅有handler属性,还有 immediate属性,默认为false,如果为true的话,则会在初始化的时候让handler调用一下。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click = "changeWeather">切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
const vm = new Vue({
el:'#root',
data:{
isHot:true

},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
isHot:{
immediate:true,
//handler什么时候调用?当isHot发生改变时
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
}
}
})
</script>
</html>

18.Vue的监视属性_html_11

从上面我们可以看到在页面初始化的时候handler就被马上调用了一下。其实配置监视还有另外一种办法,不仅仅是使用watch了。那么在讲这个别的办法之前,我们再说一个细节上的点,为以后的路扫清一些障碍。

3.2 计算属性是否可监视?

刚刚我们监视的是isHot,而isHot是谁?是我们亲手在data中配置的属性。那么这里就会引申出一个问题,我们在computed中计算出来的属性也是属性,那么它能不能监视到计算属性呢?我们可以验证一下,去监视info这个计算属性,看能不能监视到。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click = "changeWeather">切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
const vm = new Vue({
el:'#root',
data:{
isHot:true

},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
info:{
immediate:true,
//handler什么时候调用?当isHot发生改变时
handler(newValue,oldValue){
console.log('info被修改了',newValue,oldValue)
}
}
}
})
</script>
</html>

18.Vue的监视属性_vue.js_12

可以看到计算属性同样也可以监视到的。

3.3 除watch配置之外的另一种监视办法

下面我们再说一下另外一种除watch之外的监视的办法。

就是不通过watch配置,而是通过vm来实现监视。

首先我们需要保证实例已经创建完了,创建完之后,我们可以通过vm.$watch(),也能实现监视,它需要传递两个参数。第一个参数要告诉它需要监视谁,第二个参数就需要传递一个配置项来告诉他怎么监视。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天气案例</title>
<!--引入Vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<style>

</style>
</head>
<body>
<!--准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click = "changeWeather">切换天气</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止Vue在启动时生成生产提示
const vm = new Vue({
el:'#root',
data:{
isHot:true

},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{
changeWeather(){
this.isHot = !this.isHot
}
},
// watch:{
// info:{
// immediate:true,
// //handler什么时候调用?当isHot发生改变时
// handler(newValue,oldValue){
// console.log('info被修改了',newValue,oldValue)
// }
// }
// }
})
vm.$watch('isHot',{
immediate:true,
//handler什么时候调用?当isHot发生改变时
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
})
</script>
</html>

实现效果:

18.Vue的监视属性_html_13

3.4 两种监视方式的用法

上面说的两种监视方式,在实际工作中的用法是这样的。

如果我们一开始就知道需要去监视谁,那么就可以使用watch提前配置好。

如果我们一开始不知道需要监视谁,而是需要根据后续用户的一些行为来决定到底监视谁,这个时候就可以使用vm.$watch去实现动态监视。

4.总结

1.当监视属性变化时,回调函数handler自动调用,进行相关操作

2.监视的属性必须存在,才能进行监视!

3.监视的两种写法:

        (1)new Vue的时候传入watch配置

        (2)通过vm.$watch监视

举报

相关推荐

0 条评论