简记Vue3(二)—— computed、watch、watchEffect

news2024/11/28 18:53:39

个人简介

👀个人主页: 前端杂货铺
🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍍前端面试宝典 🎨100个小功能 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js实战 🍒Three.js

🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

文章目录

    • 前言
    • computed
    • watch
      • 监听 ref 定义的基本类型数据。
      • 监听 ref 定义的对象类型数据
      • 监听 reactive 定义的对象类型数据
      • 监听 ref 或 reactive 定义的对象类型数据的某个属性
      • 监视多个属性
      • watchEffect

前言

重拾 Vue3,查缺补漏、巩固基础。

computed

计算属性只读、可修改(getter setter)。

<template>
  <div class="person">
    <input type="text" v-model="firstName" /><br />
    <input type="text" v-model="lastName" /><br />
    {{ fullName }} <br />
    <button @click="changeName">changeName(computed)</button>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed } from "vue";
const firstName = ref("zhang");
const lastName = ref("san");

// 只读计算属性
// const fullName = computed(() => {
//   return (
//     firstName.value.slice(0, 1).toUpperCase() +
//     firstName.value.slice(1) +
//     "-" +
//     lastName.value
//   );
// });

// getter setter
const fullName = computed({
  get() {
    return (
      firstName.value.slice(0, 1).toUpperCase() +
      firstName.value.slice(1) +
      "-" +
      lastName.value
    );
  },
  set(val) {
    const [str1, str2] = val.split("-");
    firstName.value = str1;
    lastName.value = str2;
  },
});

function changeName() {
  fullName.value = "li-si";
}
</script>

<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

在这里插入图片描述

在这里插入图片描述


watch

Vue3 中的 watch 只能监视以下四种数据:

  • ref 定义的数据
  • reactive 定义的数据
  • 函数返回一个值(getter函数)
  • 一个包含上述内容的数组

监听 ref 定义的基本类型数据。

<template>
  <div class="person">
    {{ sum }} <br />
    <button @click="changeSum">changeSum</button>
  </div>
</template>

<script lang="ts" setup>
import { ref, watch } from "vue";
const sum = ref(0);

function changeSum() {
  sum.value += 1;
}

// sum 值大于 5 时停止监视
const stopWatch = watch(sum, (newValue, oldVallue) => {
  console.log(newValue, oldVallue);
  if (newValue > 5) {
    stopWatch();
  }
});
</script>

<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

在这里插入图片描述


监听 ref 定义的对象类型数据

修改的是 ref 定义的对象中的属性,newValue 和 oldValue 都是新值,因为它们是同一个对象。

修改整个 ref 定义的对象,newValue 是新值,oldValue 是旧值,因为不是同一个对象。

<template>
  <div class="person">
    {{ person.name }} <br />
    {{ person.age }} <br />
    <button @click="changeName">changName</button>
    <button @click="changePerson">changePerson</button>
  </div>
</template>

<script lang="ts" setup>
import { ref, watch } from "vue";
const person = ref({
  name: "zhangsan",
  age: 10,
});

function changeName() {
  person.value.name = "lisi";
}

function changePerson() {
  person.value = { name: "wangwu", age: 20 };
}

// 深度监听 person
watch(person, (newValue, oldValue) => {
    console.log(newValue, oldValue);
  },{ deep: true ));
</script>

<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

在这里插入图片描述


监听 reactive 定义的对象类型数据

监视 reactive 定义的对象类型数据时,默认开启深度监视,且无法取消。

<template>
  <div class="person">
    {{ person.name }} <br />
    {{ person.age }} <br />
    <button @click="changeName">changName</button>
    <button @click="changePerson">changePerson</button>
  </div>
</template>

<script lang="ts" setup>
import { reactive, watch } from "vue";
const person = reactive({
  name: "zhangsan",
  age: 10,
});

function changeName() {
  person.name = "lisi";
}

function changePerson() {
  Object.assign(person, { name: "wangwu", age: 20 });
}

watch(person, (newValue, oldValue) => {
  console.log(newValue, oldValue);
});
</script>

<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

在这里插入图片描述


监听 ref 或 reactive 定义的对象类型数据的某个属性

  • 若该属性值不是对象类型。需要写成函数形式
  • 若该属性值是对象类型。可以直接 . 出来,也可以写成函数(推荐)

监视的要是对象里的属性,最好写成函数式。

注意点:若监视的是地址值,需要关注对象内部,需要手动开启深度监听。

<template>
  <div class="person">
    {{ person.name }} : {{ person.age }}
    {{ person.car.c1 }}
    {{ person.car.c2 }}
    <button @click="changeName">changeName</button>
    <button @click="changeC1">changeC1</button>
    <button @click="changeC2">changeC2</button>
    <button @click="changeCar">changeCar</button>
  </div>
</template>

<script lang="ts" setup>
  import { reactive, watch } from 'vue'
  const person = reactive({
    name: '张三',
    age: 20,
    car: {
      c1: '大众',
      c2: '小米'
    }
  })

  function changeName() {
    person.name = '李四';
  }

  function changeC1() {
    person.car.c1 = '奥迪';
  }

  function changeC2() {
    person.car.c2 = '宝马';
  }

  function changeCar() {
    person.car = {c1: "雅迪", c2: "爱玛"};
  }

  watch(() => person.name, (newValue, oldValue) => {
    console.log('name changed', newValue, oldValue);
  })

  watch(() => person.car, (newValue, oldValue) => {
    console.log(newValue, oldValue);
  }, { deep: true})
</script>

<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


监视多个属性

使用数组包裹的形式,实现同时监听多个属性。

<template>
  <div class="person">
    {{ person.name }} : {{ person.age }}
    {{ person.car.c1 }}
    {{ person.car.c2 }}
    <button @click="changeName">changeName</button>
    <button @click="changeC1">changeC1</button>
    <button @click="changeC2">changeC2</button>
    <button @click="changeCar">changeCar</button>
  </div>
</template>

<script lang="ts" setup>
  import { reactive, watch } from 'vue'
  const person = reactive({
    name: '张三',
    age: 20,
    car: {
      c1: '大众',
      c2: '小米'
    }
  })

  function changeName() {
    person.name = '李四';
  }

  function changeC1() {
    person.car.c1 = '奥迪';
  }

  function changeC2() {
    person.car.c2 = '宝马';
  }

  function changeCar() {
    person.car = {c1: "雅迪", c2: "爱玛"};
  }

  watch([() => person.name, () => person.car.c1], (newValue, oldValue) => {
    console.log('name or car changed', newValue, oldValue);
  })
</script>

<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

在这里插入图片描述

在这里插入图片描述


watchEffect

watchEffect 会立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。

<template>
  <div class="person">
    <h2>当前求和为:{{ sum }}</h2>
    <button @click="changeNum">changeNum</button>
  </div>
</template>

<script lang="ts" setup>
  import { ref, watchEffect } from 'vue'

  const sum = ref(0);

  function changeNum() {
    sum.value += 1;
  }

  watchEffect(() => {
    if (sum.value < 5) {
      console.log('num changed', sum.value)
    }
  })
</script>

<style scoped>
.person {
  background-color: skyblue;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
button {
  margin: 0 5px;
}
</style>

在这里插入图片描述


参考资料:
https://www.bilibili.com/video/BV1Za4y1r7KE?spm_id_from=333.788.player.switch&vd_source=f839085517d2b7548b2939bfe214d466&p=23


在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2227496.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#从零开始学习(用户界面)(unity Lab4)

这是书本中第四个unity Lab 在这次实验中,将学习如何搭建一个开始界面 分数系统 点击球,会增加分数 public void ClickOnBall(){Score;}在OneBallBehaviour类添加下列方法 void OnMouseDown(){GameController controller Camera.main.GetComponent<GameController>();…

Bug | 项目中数据库查询问题

问题描述 理论上&#xff0c;点击查询后&#xff0c;表头应当显示中文。而不是上面的在数据库中的表头【如上图示】 正常点击查询后&#xff0c;如果没有输入值&#xff0c;应当是查询所有的信息。 原因分析&#xff1a; 这里是直接使用SELECT * 导致的。例如&#xff1a; S…

Spring Task—定时任务

Spring Task 是 Spring 提供的一种轻量级定时任务调度功能&#xff0c;内置在 Spring 框架中。与 Quartz 等重量级调度框架相比&#xff0c;Spring Task 使用简便&#xff0c;无需额外依赖&#xff0c;适合在简单的调度任务场景中使用。通过注解配置方式&#xff0c;开发者可以…

学习虚幻C++开发日志——基础案例(持续更新中)

官方文档&#xff1a;虚幻引擎C编程教程 | 虚幻引擎 5.5 文档 | Epic Developer Community | Epic Developer Community 1.物体上下起伏并旋转 1.1第一种写法 创建一个继承于Actor的类&#xff0c;并为新的Actor命名为FloatingActor&#xff0c;然后点击Create Class 重新…

前端 eslint 配置,以及在git提交之前自动format

目录 1、配置eslint步骤 1、eslint安装配置步骤 2、配置scripts步骤 3、测试eslint 2、配置git-hook1、安装环境2、最终效果 众所周知&#xff0c;前端项目可以在报很多error的情况下运行。但是良好的代码规范仍然有利于项目的开发维护&#xff0c;这里提供我的规范&#xff0c…

主动元数据平台在企业建设 DataOps 体系中的“角色”

2018 年&#xff0c;Gartner 将 DataOps 纳入到数据管理技术的成熟度曲线之中。Gartner 认为&#xff0c;DataOps 是一种协作式数据管理实践&#xff0c;改善整个组织内数据管理者和使用者之间数据流的沟通、集成和自动化&#xff0c;通过对数据、数据模型和相关工序创建可预测…

Docker搭建基于Nextcloud的个人云盘/私有云盘/个人相册/家庭NAS

安装配置Docker 官方安装文档&#xff1a;https://docs.docker.com/engine/install/ Docker常用命令&#xff1a;https://blog.csdn.net/qq_43003203/article/details/139532097?spm1001.2014.3001.5502 Docker镜像仓库配置方法和国内常用镜像仓库地址&#xff1a; 输入&a…

安卓早期apk兼容性适配之内存读写

许多早期开发的apk放到现在的高版本安卓系统上使用就会出现报错&#xff0c;今天给大家带来的是内存读写权限适配教程。 工具 mt/np管理器 早期apk dex注入器&#xff08;自行下载&#xff09; 教程 使用mt查看apk打开AndroidManifest.xml表单 在权限上添加 <!-- 读取您共享…

C++ | Leetcode C++题解之 第508题出现次数最多的子树元素和

题目&#xff1a; 题解&#xff1a; class Solution {unordered_map<int, int> cnt;int maxCnt 0;int dfs(TreeNode *node) {if (node nullptr) {return 0;}int sum node->val dfs(node->left) dfs(node->right);maxCnt max(maxCnt, cnt[sum]);return su…

三维管线管网建模工具MagicPipe3D V3.5.3

经纬管网建模系统MagicPipe3D&#xff0c;本地离线参数化构建地下管网三维模型&#xff08;包括管道、接头、附属设施等&#xff09;&#xff0c;输出标准3DTiles、Obj模型等格式&#xff0c;支持Cesium、Unreal、Unity、Osg等引擎加载进行三维可视化、语义查询、专题分析&…

【数据结构和算法】三、动态规划原理讲解与实战演练

目录 1、什么是动态规划&#xff1f; 2、动态规划实战演练 2.1 力扣题之爬楼梯问题 &#xff08;1&#xff09;解题思路1: &#xff08;2&#xff09;解题思路2: &#xff08;3&#xff09;动态规划&#xff08;DP&#xff09;&#xff1a;解题思路 &#xff08;4&#x…

PHP免杀详细讲解PHP免杀详细讲解

基础学习 可变参数 $_GET $_POST $_COOKIE $_REQUEST $_SERVER 其中的某些参数可控,如REQUESTMETHOD,QUERYSTRING,HTTPUSERAGENT等 session_id() 这个比较特殊,但是依然可以利用 $_FILE $GLOBALS getallheaders() get_defined_vars() get_defined_functions() fil…

练习LabVIEW第二十五题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第二十五题&#xff1a; 用顺序结构实现数值匹配&#xff1a;输入1-100之间的任意1个整数&#xff0c;然后系统随机产生1-…

论文解析八: GAN:Generative Adversarial Nets(生成对抗网络)

目录 1.GAN&#xff1a;Generative Adversarial Nets&#xff08;生成对抗网络&#xff09;1、标题 作者2、摘要 Abstract3、导言 IntroductionGAN的介绍 4、相关工作 Related work5、模型 Adversarial nets总结 6.理论计算 Theoretical Results具体算法公式全局优化 Global O…

【项目管理】PMP冲刺真题200题 (题目+解析)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

深度学习Pytorch-Tensor的属性、算术运算

深度学习Pytorch-Tensor的属性、算术运算 Tensor的属性Tensor的算术运算Pytorch中的in-place操作Pytorch中的广播机制Tensor的取整/取余运算Tensor的比较运算Tensor的取前k个大/前k小/第k小的数值及其索引Tensor判定是否为finite/inf/nan Tensor的属性 每一个Tensor对象都有以…

HCIP-HarmonyOS Application Developer 习题(十七)

&#xff08;判断&#xff09;1、对于用户创建的一些临时卡片在遇到卡片服务框架死亡重启&#xff0c;此时临时卡片数据在卡片管理服务中已经删除&#xff0c;且对应的卡片ID不会通知到提供方&#xff0c;所以卡片使用方需要自己负责清理长时间未刚除的临时卡片数据。 答案&…

从0开始深度学习(17)——数值稳定性和模型初始化

在每次训练之前&#xff0c;都会对模型的参数进行初始化&#xff0c;初始化方案的选择在神经网络学习中起着举足轻重的作用&#xff0c; 它对保持数值稳定性至关重要。 我们选择哪个函数以及如何初始化参数可以决定优化算法收敛的速度有多快。 糟糕选择可能会导致我们在训练时遇…

3D、VR、AR技术的应用,对家电品牌营销有哪些影响?

家电行业3D数字化营销正以其独特的优势引领着行业的变革。随着技术的不断进步和应用场景的不断拓展&#xff0c;我们有理由相信&#xff0c;未来家电行业的3D数字化营销将会更加精彩纷呈。 那么3D、VR、AR技术的应用&#xff0c;对家电品牌营销有哪些影响&#xff1f; 01、提升…

[ 问题解决篇 ] 解决远程桌面安全登录框的问题

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…