说明
vue可以通过 侦听器(watch),侦听属性,当属性值变化时,自动调用函数
注意:监听属性必须存在,才能进行侦听
侦听属性(官网叫法)有时也成为 监听属性、侦听器、监听器
应用场景
- 与 计算属性 功能类似,计算属性能实现的功能,侦听属性也都能实现,但一般较麻烦
- 校验,输入的数据不符合要求,给出提示。如:价格是 负数 或 大于最大值 时,输入内容不生效,且给出提示;电话号码输入的格式不正确时,内容不变
- 在数据变化时,发送 ajax请求,如:百度的输入框的提示
根据生日计算年龄
配置实现(完整写法)
实现下面功能,在一个输入框,输入出生年月日,就能计算出年龄,如下:
代码如下:
<div id="app">
输入出生年份:<input type="text" v-model="birthday"><br>
年龄:<span>{{age}}</span>(表达式只写监听属性名,会自动调用 监听方法)<br>
年龄:<span>{{age}}</span><br>
年龄:<span>{{age}}</span><br>
年龄:<span>{{age}}</span>(计算属性会缓存结果,如:显示4次年龄,初始化时只执行1次监听方法)
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
var vm = new Vue({
el: '#app',
data:{
birthday:'',
age:''
},
watch:{
birthday:{//要监听的属性,当该属性值发生变化,会调用handler()方法
handler(newValue,oldValue){
console.log("birthday值从 "+oldValue+" 改为 "+newValue)
this.age=new Date().getFullYear() - this.birthday.substr(0,this.birthday.indexOf("-"))
}
}
}
})
</script>
注意:监听属性必须存在,才能进行侦听
特点
- 当属性
birthday
的值 改变时,才会触发执行handler()
函数 - 函数名必须是
handler()
- 会缓存结果,如:显示4个年龄,每次只执行1次 函数。可以提高 性能
配置实现(简化写法)
<div id="app">
输入出生年份:<input type="text" v-model="birthday"><br>
年龄:<span>{{age}}</span>(表达式只写监听属性名,会自动调用 监听方法)<br>
年龄:<span>{{age}}</span><br>
年龄:<span>{{age}}</span><br>
年龄:<span>{{age}}</span>(计算属性会缓存结果,如:显示4次年龄,初始化时只执行1次监听方法)
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
var vm = new Vue({
el: '#app',
data:{
birthday:'',
age:''
},
watch:{
birthday:function(newValue,oldValue){//简化写法
console.log("birthday值从 "+oldValue+" 改为 "+newValue)
this.age=new Date().getFullYear() - this.birthday.substr(0,this.birthday.indexOf("-"))
}
}
})
</script>
动态实现
动态实现侦听属性,一般较少使用
<div id="app">
输入出生年份:<input type="text" v-model="birthday"><br>
年龄:<span>{{age}}</span>(表达式只写监听属性名,会自动调用 监听方法)<br>
年龄:<span>{{age}}</span><br>
年龄:<span>{{age}}</span><br>
年龄:<span>{{age}}</span>(计算属性会缓存结果,如:显示4次年龄,初始化时只执行1次监听方法)
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
var vm = new Vue({
el: '#app',
data:{
birthday:'',
age:''
}
})
//动态绑定侦听属性
vm.$watch('birthday',function(newValue,oldValue){
console.log("birthday值从 "+oldValue+" 改为 "+newValue)
this.age=new Date().getFullYear() - this.birthday.substr(0,this.birthday.indexOf("-"))
}
)
</script>
校验-价格
当输入价格是负数时,给出提示
引入 vue.js:
<script src="js/vue.js"></script>
样式:
<style>
.warn{
color:red;
margin-left: 10px;
}
</style>
主体代码:
<div id="app">
价格:<input type="text" v-model.number="price"><span class="warn">{{price_warn}}</span><br>
</div>
<script>
var app = new Vue({
el: '#app', //el是element缩写
data: { //数据
price:undefined, // 价格
price_warn:"", // 当价格不正确时,给出的警告
},
watch:{
price:{ // 监听price属性
// handler 必须是这个名字
//newVal:修改后的值
//oldVal 修改前的值
handler:function(newVal,oldVal){
console.log("newVal:",newVal,"--oldVal:",oldVal)
console.log("newVal类型:",typeof newVal,"--oldVal类型:",typeof oldVal)
if( newVal < 0){ //
this.price_warn = "价格不能是负数!"
}else{
this.price_warn = ""
}
}
}
}
})
</script>
immediate 属性
侦听器有 immediate
属性,为 true时,表示初始化时就执行函数,默认为false
<div id="app">
输入出生年份:<input type="text" v-model="birthday"><br>
年龄:<span>{{age}}</span>(表达式只写监听属性名,会自动调用 监听方法)<br>
年龄:<span>{{age}}</span><br>
年龄:<span>{{age}}</span><br>
年龄:<span>{{age}}</span>(计算属性会缓存结果,如:显示4次年龄,初始化时只执行1次监听方法)
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
var vm = new Vue({
el: '#app',
data:{
birthday:'',
age:''
},
watch:{
birthday:{//要监听的属性,当该属性值发生变化,会调用handler()方法
immediate:true,//为 true时,表示初始化时就执行。默认为false
handler(newValue,oldValue){
console.log("birthday值从 "+oldValue+" 改为 "+newValue)
this.age=new Date().getFullYear() - this.birthday.substr(0,this.birthday.indexOf("-"))
}
}
}
})
</script>
解释: 当 immediate
是 true
,刷新页面时,就会执行 handler()
函数
异步执行
延时1秒后执行
<div id="app">
输入出生年份:<input type="text" v-model="birthday"><br>
年龄:<span>{{age}}</span>(表达式只写监听属性名,会自动调用 监听方法)<br>
年龄:<span>{{age}}</span><br>
年龄:<span>{{age}}</span><br>
年龄:<span>{{age}}</span>(计算属性会缓存结果,如:显示4次年龄,初始化时只执行1次监听方法)
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
var vm = new Vue({
el: '#app',
data:{
birthday:'',
age:''
},
watch:{
birthday:function(newValue,oldValue){
setTimeout(() => {
console.log("birthday值从 "+oldValue+" 改为 "+newValue)
this.age=new Date().getFullYear() - this.birthday.substr(0,this.birthday.indexOf("-"))
}, 1000);
}
}
})
</script>