Vue学习:11-侦听器

在组合式API中,我们可以使用watch函数或者watchEffect函数在每次响应式状态发生变化时触发对应的回调函数。我们首先来看,怎么使用watch函数?

一、创建侦听器

语法:watch(source, callback, options)

1、source:需要侦听的数据源,可以是ref(包括计算属性)、一个响应式对象、一个 getter函数、或多个数据源组成的数组

2、callback:回调函数

a. 侦听单个数据源:回调函数的第一个参数为新值,第二个参数为旧值

b. 侦听多个数据源组成的数组:一个参数数组是新值,第二个参数数组是旧值

3、options:配置,Object类型

a. deep: true:深度侦听,一般用在侦听的是getter函数返回的对象

b. immediate: true:创建好侦听器立即执行

c. flush: 'post':更改回调的触发机制(Dom更新后)

实例1:侦听一个原始类型的数据

App.vue

<script setup>

import { ref,reactive,watch } from 'vue'

const account = ref('Abc')

const emp = reactive({
  name: 'Jack',
  salary: 7000
})

//侦听原始类型的数据变化
watch(account,(newVal,oldVal) => {
  console.log("==========账号新旧值===========")
  console.log(oldVal)
  console.log(newVal)
  console.log("===============================")
})

//侦听对象中的某一个属性变化(需要提供getter函数才可以)
//注意,你不能直接侦听响应式对象的属性值,这里需要用一个返回该属性的 getter 函数
watch(()=>emp.salary,(newVal,oldVal)=>{
  console.log('===========员工薪资新旧值===========')
  console.log(oldVal)
  console.log(newVal)
  console.log('====================================')
})

</script>

<!-- 视图区域(view) -->
<template>
  账号:<input type="text" v-model="account">
  <br>
  <br>
  员工薪资:<input type="number" v-model="emp.salary">
</template>

<style>
  
</style>

实例2:侦听一个对象类型的数据

App.vue

<script setup>

import { ref,reactive,watch } from 'vue'

let emp = reactive({
  name: 'Jack',
  salary: 7000
})

let dept = reactive({
  id: '101',
  name: '销售部'
})

let region = reactive({
  id: '201',
  name: '北美洲'
})

//侦听对象,直接给 watch() 传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发
//如果嵌套属性值发生变化,那么也会触发该回调函数,但是newVal,oldVal是相等的,因为它们是同一个对象
watch(emp,(newVal,oldVal) => {
  console.log("==========员工信息新旧值===========")
  console.log(oldVal)
  console.log(newVal)
  console.log("===============================")
})

//侦听:对象(getter)
//一个返回响应式对象的 getter 函数,只有在返回不同的对象时,才会触发回调
//所以下面的代码是无法触发该回调函数
watch(()=>dept,(newVal,oldVal) => {
  console.log("=============部门信息新旧值=============")
  console.log(oldVal)
  console.log(newVal)
  console.log("========================================")
})

//可以给上面这个例子显式地加上 deep 选项,强制转成深层侦听器,但是newVal,oldVal是相等的,因为它们是同一个对象
watch(()=>region,
  (newVal,oldVal) => {
    console.log("=============区域名称新旧值=============")
    console.log(oldVal)
    console.log(newVal)
    console.log("========================================")
  },
  {deep: true}
)
</script>

<!-- 视图区域(view) -->
<template>  
  员工薪资:<input type="number" v-model="emp.salary">
  <hr>
  部门名称:<input type="text" v-model="dept.name">
  <hr>
  区域名称:<input type="text" v-model="region.name">
</template>

<style>
  
</style>

谨慎使用:深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。

实例3:侦听多个数据源组成的数组

App.vue

<script setup>

import { ref,reactive,watch } from 'vue'

let account = ref('Abc')

let emp = reactive({
  name: 'Jack',
  salary: 7000
})

let dept = reactive({
  id: '101',
  name: '销售部'
})


//侦听多个数据源组成的数组
watch([account,()=>emp.salary,dept],
  ([newAccount,newSalary,newDept],[oldAccount,oldSalary,oldDept]) =>{
    console.log("=====账号新旧值=====")
    console.log(newAccount)
    console.log(oldAccount)
    console.log("====================")
    console.log("=====薪资新旧值=====")
    console.log(newSalary)
    console.log(oldSalary)
    console.log("====================")
    console.log("=====部门新旧值=====")
    console.log(newDept)
    console.log(oldDept)
    console.log("====================")
  })

</script>

<!-- 视图区域(view) -->
<template>  
  账号:<input type="text" v-model="account">
  <hr>
  员工薪资:<input type="number" v-model="emp.salary">
  <hr>
  部门名称:<input type="text" v-model="dept.name">
  <hr>
  
</template>

<style>
  
</style>

实例4:侦听器配置选项

App.vue

<script setup>

import { ref,reactive,watch } from 'vue'

let account = ref('Abc')

let emp = reactive({
  name: 'Jack',
  salary: 7000
})

let password = ref('123456')

//创建完侦听器后立即执行一遍
watch(
  account,
  (newVal,oldVal) => {
    console.log('账号变化:')
    console.log(newVal)
    console.log(oldVal)
    console.log('==========')
  },
  {immediate:true}  
)

//深度侦听,侦听函数返回的对象时,其嵌套属性值发生变化,依然可以触发回调函数,但是新旧值相等
watch(
  ()=>emp,
  (newVal,oldVal) => {
    console.log('员工变化:')
    console.log(newVal)
    console.log(oldVal)
    console.log('==========')
  },
  {deep:true}
)

//更改回调函数的触发机制(Dom更新之后)
watch(
  password,
  (newVal,oldVal) => {
    console.log('密码变化:')
    console.log(newVal)
    console.log(oldVal)
    //默认情况下回调的触发机制在Dom更新之前执行
    console.log(document.getElementById('titlePassword').innerHTML)
  },
  {flush: 'post'}
)

</script>

<!-- 视图区域(view) -->
<template>  
  账号:<input type="text" v-model="account">
  <hr>
  员工薪资:<input type="number" v-model="emp.salary">
  <hr>
  <h1 id="titlePassword">
    密码:
    <i>{{ password }}</i>
  </h1>
  密码:<input type="text" v-model="password">
  <hr>
  
</template>

<style>
  
</style>

二、停止侦听器

调用watch()返回的函数即可

App.vue

<script setup>

import { ref,watch } from 'vue'

let account = ref('Abc')

let stopAccountWatch = watch(
  account,
  (newVal,oldVal) => {
    console.log('账号变化:')
    console.log(newVal)
    console.log(oldVal)
    console.log('==========')
  }
)

</script>

<!-- 视图区域(view) -->
<template>  
  账号:<input type="text" v-model="account">
  <hr>
  <button @click="stopAccountWatch">停止账号侦听器</button>
  
</template>

<style>
  
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值