0

0

聊聊vue3中watch和computed的使用方法

青灯夜游

青灯夜游

发布时间:2023-04-14 15:04:44

|

3079人浏览过

|

来源于csdn

转载

本篇文章带大家学习vue3,深入聊聊计算属性computed与侦听器watch的使用方法,希望对大家有所帮助!

聊聊vue3中watch和computed的使用方法

一、watch

1.检测reactive内部数据

<template>
  <p>{{ obj.hobby.eat }}</p>
  <button @click="obj.hobby.eat = '面条'">click</button>
</template>

<script>
  import { watch, reactive } from 'vue'
  export default {
      name: 'App',
      setup() {
          const obj = reactive({
              name: 'ifer',
              hobby: {
                  eat: '西瓜',
              },
          })
          watch(obj, (newValue, oldValue) => {
              // 注意1:监听对象的时候,新旧值是相等的
              // 注意2:强制开启深度监听,配置无效
              console.log('触发监听');
              console.log(newValue === oldValue) // true
          })

          return { obj }
      },
  }
</script>

注意点:对 reactive 自身的修改则不会触发监听。【相关推荐:vuejs视频教程web前端开发

立即学习前端免费学习笔记(深入)”;

<template>
    <p>{{ obj.hobby.eat }}</p>
    <button @click="obj.hobby = { eat: '面条' }">click</button>
</template>

<script>
    import { watch, reactive } from 'vue'
    export default {
        name: 'App',
        setup() {
            const obj = reactive({
                name: 'ifer',
                hobby: {
                    eat: '西瓜',
                },
            })
            watch(obj.hobby, (newValue, oldValue) => {
                // obj.hobby = { eat: '面条' }
                console.log('对 reactive 自身的修改不会触发监听')
            })
            return { obj }
        },
    }
</script>

点击确定不触发watch

一定得注意不能修改reactive本身,修改本身不触发

2.监听 ref 数据

  • 2.1监听一个 ref 数据
<template>
  <p>{{ age }}</p>
  <button @click="age++">click</button>
</template>

<script>
  import { watch, ref } from 'vue'
  export default {
      name: 'App',
      setup() {
          const age = ref(18)
          // 监听 ref 数据 age,会触发后面的回调,不需要 .value
          watch(age, (newValue, oldValue) => {
              console.log(newValue, oldValue)
          })

          return { age }
      },
  }
</script>
  • 2.2监听多个 ref 数据

可以通过数组的形式,同时监听 age 和 num 的变化。

<template>
    <p>age: {{ age }} num: {{ num }}</p>
    <button @click="handleClick">click</button>
</template>

<script>
    import { watch, ref } from 'vue'
    export default {
        name: 'App',
        setup() {
            const age = ref(18)
            const num = ref(0)

            const handleClick = () => {
                age.value++
                num.value++
            }
            // 数组里面是 ref 数据
            watch([age, num], (newValue, oldValue) => {
                console.log(newValue, oldValue)
            })

            return { age, num, handleClick }
        },
    }
</script>

点击数量++

立即触发监听属性:

                {
                    immediate: true,
                }
<template>
    <p>{{ age }}</p>
    <button @click="handleClick">click</button>
</template>

<script>
    import { watch, ref } from 'vue'
    export default {
        name: 'App',
        setup() {
            const age = ref(18)

            const handleClick = () => {
                age.value++
            }

            watch(
                age,
                (newValue, oldValue) => {
                    console.log(newValue, oldValue) // 18 undefined
                },
                {
                    immediate: true,
                }
            )

            return { age, handleClick }
        },
    }
</script>

watch监听ref数据

开启深度监听 ref 数据

AI Note
AI Note

AI Note 助手,像贴心女仆一样助力你的笔记!智能总结内容,精确划重点,提供专业建议,让学习与工作更高效。让你的笔记更清晰、有条理,知识尽在眼前!

下载
? 问题:修改 ref 对象里面的数据并不会触发监听,说明 ref 并不是默认开启 deep 的。见下
<template>
    <p>{{ obj.hobby.eat }}</p>
    <button @click="obj.hobby.eat = '面条'">修改 obj.hobby.eat</button>
</template>

<script>
    import { watch, ref } from 'vue'
    export default {
        name: 'App',
        setup() {
            const obj = ref({
                hobby: {
                    eat: '西瓜',
                },
            })
            // 注意:ref 监听对象,默认监听的是这个对象地址的变化
            watch(obj, (newValue, oldValue) => {
                console.log(newValue === oldValue)
            })

            return { obj }
        },
    }
</script>

没有触发打印ture/false
面对这样的没有触发watch我们解决办法有三个:

  • 解决 1:当然直接修改整个对象的话肯定是会被监听到的(注意模板中对 obj 的修改,相当于修改的是 obj.value)。
    -`

    {{ obj.hobby.eat }}

`

解决方法1

  • 解决 2:开启深度监听 ref 数据。
watch(
    obj,
    (newValue, oldValue) => {
        console.log(newValue, oldValue)
        console.log(newValue === oldValue)
    },
    {
        deep: true,
    }
)

就加上一句话,故此没有截图

  • 解决 3:还可以通过监听 ref.value 来实现同样的效果。

因为 ref 内部如果包裹对象的话,其实还是借助 reactive 实现的,可以通过 isReactive 方法来证明。

<template>
    <p>{{ obj.hobby.eat }}</p>
    <button @click="obj.hobby.eat = '面条'">修改 obj</button>
</template>

<script>
    import { watch, ref } from 'vue'
    export default {
        name: 'App',
        setup() {
            const obj = ref({
                hobby: {
                    eat: '西瓜',
                },
            })
            watch(obj.value, (newValue, oldValue) => {
                console.log(newValue, oldValue)
                console.log(newValue === oldValue)
            })

            return { obj }
        },
    }
</script>

解决方案3

  • 监听普通数据
    监听响应式对象中的某一个普通属性值,要通过函数返回的方式进行(如果返回的是对象/响应式对象,修改内部的数据需要开启深度监听)。
<template>
    <p>{{ obj.hobby.eat }}</p>
    <button @click="obj.hobby.eat = '面条'">修改 obj</button>
</template>

<script>
    import { watch, reactive } from 'vue'
    export default {
        name: 'App',
        setup() {
            const obj = reactive({
                hobby: {
                    eat: '西瓜',
                },
            })
            // 把 obj.hobby 作为普通值去进行监听,只能监听到 obj.hobby 自身的变化
            /* watch(
      () => obj.hobby,
      (newValue, oldValue) => {
        console.log(newValue, oldValue)
        console.log(newValue === oldValue)
      }
    ) */
            // 如果开启了深度监听,则能监听到 obj.hobby 和内部数据的所有变化
            /* watch(
      () => obj.hobby,
      (newValue, oldValue) => {
        console.log(newValue, oldValue)
        console.log(newValue === oldValue)
      },
      {
        deep: true,
      }
    ) */
            // 能监听影响到 obj.hobby.eat 变化的操作,例如 obj.hobby = { eat: '面条' } 或 obj.hobby.eat = '面条',如果是 reactive 直接对 obj 的修改则不会被监听到(ref 可以)
            watch(
                () => obj.hobby.eat,
                (newValue, oldValue) => {
                    console.log(newValue, oldValue)
                    console.log(newValue === oldValue)
                }
            )
            return { obj }
        },
    }
</script>

二、computed

作用:computed 函数用来定义计算属性,上述的基础概念都是同vue2一样的,关于vue2中这两个知识点的定义大家可以移步:【vue2】计算与侦听的用法

<template>
  <p>firstName: {{ person.firstName }}</p>
  <p>lastName: {{ person.lastName }}</p>
  <input type="text" v-model="person.fullName" />
</template>
<script>
  import { computed, reactive } from 'vue'
  export default {
      name: 'App',
      setup() {
          const person = reactive({
              firstName: '初',
              lastName: '映',
          })
          // 也可以传入对象,目前和上面等价
          person.fullName = computed({
              get() {
                  return person.firstName + '*' + person.lastName
              },
              set(value) {
                console.log(value,'value');//为上述get的返回值
                  const newArr = value.split('*')
                  person.firstName = newArr[0]
                  person.lastName = newArr[1]
              },
          })
          return {
              person,
          }
      },
  }
</script>

value为get的返回值

(学习视频分享:vuejs入门教程编程基础视频

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

0

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

22

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

48

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

93

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

216

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

413

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

143

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

221

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

31

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 5.9万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号