vue中的侦听器
初探侦听器
虽然计算属性在大多数情况下更合适, 但有时也需要一个自定义的侦听器。 这就是为什么Vue通过watch选项提供了一个更通用的方法来响应数据的变化。
当需要在数据变化时执行异步或开销较大的操作时, 这个方式是最有用的, 比如ajax请求时, 对数据变化的侦听。
使用watch选项允许我们执行异步操作(访问一个API), 并设置一个执行改操作的条件, 这些都是计算属性无法做到的。
<script>
export default {
data () {
return {
message: 'helloworld'
}
},
methods: {
},
computed: {
},
/**
* 侦听数据的变化
* 侦听数据时, 不需要用this, 直接侦听哪一个属性, 直接写就可以, 后面跟一个函数
* 侦听器有两个默认的值, 一个是newValue, 另外一个是oldValue, 这个名称可以自定义
*
* 使用watch选项允许我们执行异步操作(访问一个API), 并设置一个执行改操作的条件, 这些都是计算属性无法做到的。
*
* 当message发生改变时, 会触发侦听器
*
* 侦听器, 一个数据影响多个数据, 比如message发生改变, 多个数据发生改变
*/
watch:{
// 侦听message, message就是data里面的一个属性, 每当message发生变化时, 都会调用这个函数,
message:function(newValue,oldValue){
// oldValue如果没有使用上, 可以直接不写
console.log('侦听message的变化,新的值是: '+newValue+' 之前旧的值为: '+oldValue)
// 这里面可以执行异步操作或者复杂的代码,比如向后台发送一些ajax请求,获取数据,然后赋值给data里面的变量
}
}
}
</script>
<template>
<!-- template就是模版 -->
<div>
<p>{{ message }}</p>
<p>
<button @click="message='你好呀'">改变message</button>
</p>
</div>
</template>
<style></style>
深度侦听
deep参数是bool, 表示是否深度监听, 开启后, 对这个对象里面所有元素进行监听, 侦听器会一层一层向下遍历, 给对象的每一个属性都加上侦听器。
使用字符串的形式进行优化, 只会单独侦听对象中对应的属性
示例是侦听user里面的name属性
data () {
return {
user:{
name:'李白',
age:18
}
}
},
...............................................
watch:{
"user.name":{
// immediate是个布尔值, 为true的时候表示初始化的时候调用函数
immediate:true,
handler:function(newValue){
console.log('newValue',newValue)
},
// deep参数是bool, 表示是否深度监听
deep:true,
}
}
示例:
<script>
export default {
data () {
return {
message: 'helloworld',
tips: 'tips121',
user:{
name:'李白',
age:18
}
}
},
methods: {
},
computed: {
},
watch:{
// 当message发生变化时, 都会调用这个函数
// 监听的简写
// message函数里面有2个参数, 如果oldValue没用到, 后面这个参数可以不写
message:function(newValue,oldValue){
// console.log('侦听message的变化,新的值是: '+newValue+' 之前旧的值为: '+oldValue)
// 这里面可以执行异步操作或者复杂的代码,比如向后台发送一些ajax请求,获取数据,然后赋值给data里面的变量
// 新值必须在5-10之间
if(newValue.length < 5 || newValue.length > 10)
{
// 进行一些逻辑操作,复杂逻辑的都可以放在这里面
console.log('侦听message的长度, 输入框的内容不能小于5或者大于10')
}
},
// 监听的完整写法, 深度监听
tips:{
immediate:true, // immediate是个布尔值, 为true的时候表示初始化的时候调用函数
handler:function(newValue,oldValue){
// 初始化的时候, 就会拿到这个值, 此时的newValue打印出就是初始化的字符串`tips`
console.log(' 监听newValue',newValue)
if(newValue.length < 5 || newValue.length > 10){
console.log('侦听tips的长度, 输入框的内容不能小于5或者大于10')
}
}
},
// 侦听函数里面有2个参数, 如果oldValue没用到, 后面这个参数可以不写
// user:function(newValue){
// console.log(' 监听user',newValue)
// }
// user:{
// handler:function(newValue){
// console.log('newValue',newValue)
// },
// /**
// * deep参数是bool, 表示是否深度监听, 开启后, 对这个对象里面所有元素进行监听
// * 侦听器会一层一层向下遍历, 给对象的每一个属性都加上侦听器
// */
// deep:true,
// }
/**
* 优化只深度侦听对象里面的对应属性
* 写成user.name字符串形式, 依然要开启深度监听, 这样只会监听user里面的name属性, 不然
* 侦听器会一层一层向下遍历, 给对象的每一个属性都加上侦听器,这样性能开销很大
*/
'user.name':{ // 使用字符串的形式进行优化, 只会单独侦听对象中对应的属性
handler:function(newValue){
console.log('newValue',newValue)
},
/**
* deep参数是bool, 表示是否深度监听, 开启后, 对这个对象里面所有元素进行监听
* 侦听器会一层一层向下遍历, 给对象的每一个属性都加上侦听器
*/
deep:true,
}
}
}
</script>
<template>
<!-- template就是模版 -->
<div>
<p>{{ message }}</p>
<p>{{ tips }}</p>
<p>
<button @click="message='你好呀'">改变message</button>
</p>
<!-- v-model 数据的双向绑定 -->
<p><input type="text" v-model="message"></p>
<p><input type="text" v-model="tips"></p>
<!-- 深度监听user里面的name
监听不到对象中的属性变化,这个时候就需要使用深度监听
-->
<p>{{ user.name }}</p>
<p>{{ user.age }}</p>
<button @click="user.name = '羊小羊'">改变名字</button>
<button @click="user.age = 20">改变年龄</button>
</div>
</template>
<style></style>