Vue侦听器(watch)的实践分享

前言

复制代码
在开发中遇到一个需求:

现有A、B两页面,其中B页面是A页面的新页面(不是父子组件关系),要求:A页面传递id参数,B页面接收传递参数,当A页面不传递参数(undefined)或传空时,B页面保持原先A页面传递过来的id值(B页面接收的参数不可能为空) 即:

  1. A(id=1) => B(id=1)
  2. A(不传&id=undefined) => B(id=1)
  3. A(id=2) => B(id=2)
  4. ...

Vue侦听器(watch)

在前言中提到的需求,实现的方法有多种,例如 (以下将侦听器更换名为监听器)

  • sessionStorage (会话存储) 和 localStorage(本地存储)
  • Vue状态管理器
  • Vue监听器(watch)
  • ....

本文主要以 Vue监听器(watch) 为方法进行实现(主要还是回顾Vue内置的监听方法使用) vue官网-侦听器

在watch函数中支持监听以下三种数据源类型

javascript 复制代码
const x = ref(0)
const y = ref(0)

// 单个 ref
watch(x, (newX) => {
  console.log(`x is ${newX}`)
})

// getter 函数
watch(() => x.value + y.value,(sum) => {
    console.log(`sum of x + y is: ${sum}`)
  }
)

// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {
  console.log(`x is ${newX} and y is ${newY}`)
})
//注意,watch监听器无法直接监听响应式对象的属性值,需要使用getter函数方式去进行监听

实现

以上就是监听器大致使用,进入正题,实现前言的需求

  1. A页面通过点击事件携带id参数跳转至B页面
javascript 复制代码
//A页面
const bindHandleA= (id)=>{
	router.push({
    	name: "B页面",
        query: {id}
    });
}
  1. B页面接收A页面传递过来的参数
javascript 复制代码
//B页面
const parA = ref(); //接收参数
parA.value = route.query.id
  1. 通过onActivated或onMounted生命周期方法进行监听每次传递id的值
javascript 复制代码
let webId = null;
const newActive = ref(false);
onMounted(() => {
	webId = route.query.id;
    watch(()=>route.query.id,(newID,oldID) => {
    	if(newID === undefined || newID === ''){
        	webId = oldID;
            newActive.value = false;
       	}
        if(oldID === undefined){
             webId = newID;
             newActive.value = true;
        }
        if(newActive.value){
        //接收传递过来的id值	
             console.log(webId);
        }
     });
});
/* 或者可以用onActivated */
onActivated(() => {   
    watch(()=>route.query.id,(newID,oldID) => {
        if(newID === undefined || newID === ''){
            webId = oldID;
            newActive.value = false;
            return;
        }
        if(oldID === undefined){
            webId = newID;
            newActive.value = true;
            return;
        }
    });
    if(newActive.value){
    //接收传递过来的id值
        console.log(webId);
    }
})
  1. 完成,无论A页面传递什么id值过来都能保持最新状态同时当A页面传值为空时,在监听中保存了有上一次记录值,依旧能够有记录值在此保存着

补充

深层监听

监听器的深层监听,以上面的代码为例

javascript 复制代码
watch(()=>route.query.id,(newID,oldID) => {
	if(newID === undefined || newID === ''){
    	webId = oldID;
        newActive.value = false;
        return;
    }
    if(oldID === undefined){
        webId = newID;
        newActive.value = true;
        return;
    }
  });
    if(newActive.value){
    //接收传递过来的id值
        console.log(webId);
    }
},{deep: true})

通过deep:true开启强制深层监听

注意

开启了深层监听是无法实现前言提到的需求因为传递回的newID,oldID是相等一样的

在Vue官网介绍中,直接给 watch() 传入一个响应式对象,会隐式地创建一个深层侦听器------该回调函数在所有嵌套的变更时都会被触发:

javascript 复制代码
const obj = reactive({ count: 0 })

watch(obj, (newValue, oldValue) => {
  // 在嵌套的属性变更时触发
  // 注意:`newValue` 此处和 `oldValue` 是相等的
  // 因为它们是同一个对象!
})

obj.count++

相比之下,一个返回响应式对象的 getter 函数,只有在返回不同的对象时,才会触发回调:

javascript 复制代码
watch(
  () => state.someObject,
  () => {
    // 仅当 state.someObject 被替换时触发
  }
)

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

即时回调的侦听器

watch函数是懒执行状态,只有监听数据源变化时才能执行watch函数回调 通过传入 immediate: true 选项来强制侦听器的回调立即执行:

javascript 复制代码
watch(
  source,
  (newValue, oldValue) => {
    // 立即执行,且当 `source` 改变时再次执行
  },
  { immediate: true }
)

watchEffect()

在vue官网中的介绍是:侦听器的回调使用与源完全相同的响应式状态是很常见的。例如下面的代码,在每当 todoId 的引用发生变化时使用侦听器来加载一个远程资源:

javascript 复制代码
const todoId = ref(1)
const data = ref(null)

watch(
  todoId,
  async () => {
    const response = await fetch(
      `https://jsonplaceholder.typicode.com/todos/${todoId.value}`
    )
    data.value = await response.json()
  },
  { immediate: true }
)

通过watchEffect来简化上述监听函数不需要immediate: true

javascript 复制代码
watchEffect(async () => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/todos/${todoId.value}`
  )
  data.value = await response.json()
})

这个例子中,回调会立即执行,不需要指定 immediate: true。在执行期间,它会自动追踪 todoId.value 作为依赖(和计算属性类似)。每当 todoId.value 变化时,回调会再次执行。有了 watchEffect(),我们不再需要明确传递 todoId 作为源值。

结尾

以上就是Vue侦听器(watch)的实践分享的全部内容,在补充中有很多都是Vue官网中的案例和介绍,就不再叙述补充了,详细可以去查看Vue官网中的介绍案例,如不理解的地方欢迎讨论。

Vue官网侦听器

相关推荐
Xf3n1an6 分钟前
html语法
前端·html
张拭心8 分钟前
亚马逊 AI IDE Kiro “狙击”Cursor?实测心得
前端·ai编程
烛阴24 分钟前
为什么你的Python项目总是混乱?层级包构建全解析
前端·python
@大迁世界1 小时前
React 及其生态新闻 — 2025年6月
前端·javascript·react.js·前端框架·ecmascript
红尘散仙2 小时前
Rust 终端 UI 开发新玩法:用 Ratatui Kit 轻松打造高颜值 CLI
前端·后端·rust
新酱爱学习2 小时前
前端海报生成的几种方式:从 Canvas 到 Skyline
前端·javascript·微信小程序
袁煦丞2 小时前
把纸堆变数据流!Paperless-ngx让文件管理像打游戏一样爽:cpolar内网穿透实验室第539个成功挑战
前端·程序员·远程工作
慧慧吖@2 小时前
关于两种网络攻击方式XSS和CSRF
前端·xss·csrf
徐小夕2 小时前
失业半年,写了一款多维表格编辑器pxcharts
前端·react.js·架构
LaoZhangAI3 小时前
Kiro vs Cursor:2025年AI编程IDE深度对比
前端·后端