vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue3 watch监听

详解vue3中watch监听的几种情况

作者:蓝色海岛

watch是CompositionAPI的一部分,用于监听响应式数据的变化并执行相应的操作,本文主要介绍了详解vue3中watch监听的几种情况,具有一定的参考价值,感兴趣的可以了解一下

一、监听ref创建的基本数据类型

watch的第一个参数直接写需要监听的数据名即可,监听的是其值的变化
    <div>
      <h1>情况一:监视【ref】定义的【基本类型】数据</h1>
      <h2>当前求和为:{{ sum }}</h2>
      <el-button @click="changeSum">点我sum+1</el-button>
    </div>
    
// 数据
let sum = ref(0)
// 方法
function changeSum() {
  sum.value += 1
}
// 监视,情况一:监视【ref】定义的【基本类型】数据
const stopWatch = watch(sum, (newValue, oldValue) => {
  console.log('sum变化了', newValue, oldValue)
  if (newValue >= 10) {
    stopWatch()
  }
})

二、监听ref创建的对象类型

watch监听person时,监听的是person的地址值,只有当person的引用地址发生变化时才能监听得到,当写成Object.assign(person.value, { name: '李四', age: 90, son: { age: 5 } })时依然监听不到
当开启deep: true时,无论修改person中的哪个参数,包括son对象,都能监听得到

   <div>
      <h1>情况二:监视【ref】定义的【对象类型】数据</h1>
      <h2>姓名:{{ person.name }}</h2>
      <h2>年龄:{{ person.age }}</h2>
      <h2>儿子年龄:{{ person.son.age }}</h2>
      <el-button @click="changeName">修改名字</el-button>
      <el-button @click="changeAge">修改年龄</el-button>
      <el-button @click="changePerson">修改整个人</el-button>
      <el-button @click="changeSonAge">修改儿子年龄</el-button>
    </div>
    
// 数据
let person = ref({
  name: '张三',
  age: 18,
  son: { age: 5 }
})
// 方法
function changeName() {
  person.value.name += '~'
}
function changeAge() {
  person.value.age += 1
}
function changePerson() {
  person.value = { name: '李四', age: 90, son: { age: 5 } }
}
function changeSonAge() {
  person.value.son.age += 1
}
watch(
  person,
  (newValue, oldValue) => {
    console.log('person变化了', newValue, oldValue)
  },
  { deep: true }
)

三、监听reactive定义的对象类型数据,会默认开启深度监听

前面提到,如果是监听ref创建的对象类型数据,需要手动开启深度监听,而监听reactive创建的对象类型数据时,会自动开启深度监听

  <div>
      <h1>情况三:监视【reactive】定义的【对象类型】数据</h1>
      <h2>姓名:{{ person.name }}</h2>
      <h2>年龄:{{ person.age }}</h2>
      <el-button @click="changeName">修改名字</el-button>
      <el-button @click="changeAge">修改年龄</el-button>
      <el-button @click="changePerson">修改整个人</el-button>
      <hr />
      <h2>测试:{{ obj.a.b.c }}</h2>
      <el-button @click="test">修改obj.a.b.c</el-button>
    </div>
    
// 数据
let person = reactive({ name: '张三', age: 18 })
let obj = reactive({ a: { b: { c: 666 } } })
// 方法
function changeName() {
  person.name += '~'
}
function changeAge() {
  person.age += 1
}
function changePerson() {
  Object.assign(person, { name: '李四', age: 80 })
}
function test() {
  obj.a.b.c += 888
}

// 监视,情况三:监视【reactive】定义的【对象类型】数据,且默认是开启深度监视的
watch(person, (newValue, oldValue) => {
  console.log('person变化了', newValue, oldValue)
})
watch(obj, (newValue, oldValue) => {
  console.log('Obj变化了', newValue, oldValue)
})

四、监听ref或reactive定义的对象类型中的某个属性

监听的是对象的基本类型数据,要写成函数形式
监听的是对象的对象类型数据,可以写成函数形式,也可以直接写
监听的是对象的对象类型数据,并且改变对象时改变了应用地址,例如person.car = { ... },就必须要写成函数形式

 <div>
      <h1>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1>
      <h2>姓名:{{ person.name }}</h2>
      <h2>年龄:{{ person.age }}</h2>
      <h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
      <el-button @click="changeName">修改名字</el-button>
      <el-button @click="changeAge">修改年龄</el-button>
      <el-button @click="changeC1">修改第一台车</el-button>
      <el-button @click="changeC2">修改第二台车</el-button>
      <el-button @click="changeCar">修改整个车</el-button>
    </div>
    
// 数据
let person = reactive({ name: '张三', age: 18, car: { c1: '奔驰', c2: '宝马' } })
// 方法
function changeName() {
  person.name += '~'
}
function changeAge() {
  person.age += 1
}
function changeC1() {
  person.car.c1 = '奥迪'
}
function changeC2() {
  person.car.c2 = '大众'
}
function changeCar() {
  // person.car = { c1: '雅迪', c2: '爱玛' }
  Object.assign(person.car, { c1: '雅迪', c2: '爱玛' })
}
// 监视,情况四:监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
watch(
  () => person.name,
  (newValue, oldValue) => {
    console.log('person.name变化了', newValue, oldValue)
  }
)
watch(
  () => person.car, // 如果使用 person.car = { ... } 必须要使用函数写法;如果使用Object.assign,可以直接写person.car
  (newValue, oldValue) => {
    console.log('person.car变化了', newValue, oldValue)
  },
  { deep: true }
)

如果需要监听多个数据,可以将2个watch合并为一个:

watch(
  [() => person.name, () => person.car],
  (newValue, oldValue) => {
    console.log('person.car变化了', newValue, oldValue)
  },
  { deep: true }
)

总结:

监听ref创建的基本数据类型,必须直接写,不可以写成函数形式
监听ref创建的对象数据类型,可以直接写,也可以写成函数形式,需要开启deep: true
监听reactive创建的对象数据类型,必须直接写,不可以写成函数形式,默认开启了deep: true
监听ref或reactive创建的对象类型中的某个属性,该类型为基本数据类型,必须写成函数形式
监听ref或reactive创建的对象类型中的某个属性,该类型为对象数据类型,可以直接写,也可以写成函数形式,需要开启deep: true。如果想要监听引用地址变化,必须写成函数形式

序号情况是否使用函数写法是否需要手动开启深度监听
1监听ref创建的基本数据类型否。必须直接写,不可以写成函数形式
2监听ref创建的对象数据类型皆可。可以直接写,也可以写成函数形式
3监听reactive创建的对象数据类型否。必须直接写,不可以写成函数形式否。默认开启了深度监听
4监听ref或reactive创建的对象类型中的某个属性,该类型为基本数据类型是。必须写成函数形式
5监听ref或reactive创建的对象类型中的某个属性,该类型为对象数据类型皆可。可以直接写,也可以写成函数形式;如果想要监听引用地址变化,必须写成函数形式

到此这篇关于详解vue3中watch监听的几种情况的文章就介绍到这了,更多相关vue3 watch监听内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文