Vue3 - 从 vue2 到 vue3 过渡,这一套就够了(案例 + 效果演示)(二)

目录

一、组合式 API 的使用

1.1、watch 函数

1.2、watchEffect 函数

1.3、toRef 和 toRefs

1.3.1、toRef

1.3.2、toRefs

1.4、vue3  的声明周期


 

一、组合式 API 的使用


1.1、watch 函数

与 vue2.x 中的 watch 配置功能一致,但是多了一些坑:

这是我当前的 vue 版本

  1. 监视 reactive 定义的响应式数据时:oldValue 无法正确获取
  2. 监视 reactive 定义的响应式数据中某个属性时:deep 配置有效.

Ps:我目前使用的 vue3 的版本没有以上问题!!!

这里我来列出几种情况:

a)监视 ref 所定义的响应式数据

<template>
  <h2>当前和为: {{ sum }}</h2>
  <button @click="sum++">点我 + 1</button>
</template>

<script>
import { ref, watch } from "vue";
export default {
  name: "App",
  setup() {
    let sum = ref(0);

    watch(sum, (newValue, ordValue) => {
      console.log("sum变了", newValue, ordValue);
    });

    return {
      sum,
    };
  },
};
</script>

监视没有问题,如下:

b)监视 ref 定义的多个响应式数据(只要其中一个变,就会触发监视事件)

<template>
  <h2>当前和为: {{ sum }}</h2>
  <h2>{{ msg }}</h2>
  <button @click="sum++">点我 + 1</button>
  <button @click="msg += '!'">点我 + !</button>
</template>

<script>
import { ref, watch } from "vue";
export default {
  name: "App",
  setup() {
    let sum = ref(0);
    let msg = ref("你好呀");

    //情况二
    watch([sum, msg], (newValue, oldValue) => {
      console.log("sum 或 msg 变了", newValue, oldValue);
    });

    return {
      sum,
      msg,
    };
  },
};
</script>

先点三下 “点我 + 1”、再点三下 “点我 + !”,效果如下:

c)监视 reactive 所定义的一个响应式数据的全部属性,无法正确的获取 oldValue

若没有配置 deep,默认开启深度监视(老版本的 vue3 强制开启深度监视,无法修改,我当前使用的版本已修改该问题).

<template>
  <h2>一个人的信息</h2>
  <div>{{ person.name }}</div>
  <div>{{ person.age }}</div>
  <div>{{ person.a.b.c }}</div>
  <button @click="person.name = 'lyj'">修改姓名</button>
  <button @click="person.age += 1">修改年龄</button>
  <button @click="person.a.b.c += 100">修改a.b.c</button>
</template>

<script>
import { reactive, ref, watch } from "vue";
export default {
  name: "App",
  setup() {
    let person = reactive({
      name: "cyk",
      age: 18,
      a: {
        b: {
          c: 666,
        },
      },
    });

    //情况三
    watch(
      person,
      (newValue, oldValue) => {
        console.log("person变化了", newValue, oldValue);
      },
    );

    return {
      person,
    };
  },
};
</script>

依次点击按钮,效果如下:

若设置 deep 为 false ,则点击 “修改 a.b.c ” 无效,如下:

<template>
  <h2>一个人的信息</h2>
  <div>{{ person.name }}</div>
  <div>{{ person.age }}</div>
  <div>{{ person.a.b.c }}</div>
  <button @click="person.name = 'lyj'">修改姓名</button>
  <button @click="person.age += 1">修改年龄</button>
  <button @click="person.a.b.c += 100">修改a.b.c</button>
</template>

<script>
import { reactive, ref, watch } from "vue";
export default {
  name: "App",
  setup() {
    let person = reactive({
      name: "cyk",
      age: 18,
      a: {
        b: {
          c: 666,
        },
      },
    });

    //情况三
    watch(
      person,
      (newValue, oldValue) => {
        console.log("person变化了", newValue, oldValue);
      },
      { deep: false } //此处 deep 配置有效!!版本更新,修复了之前无效的问题
    );

    return {
      person,
    };
  },
};
</script>

d)监视 reactive 所定义的一个响应式数据中的某个属性,这样可以解决上述请款三无法正确显示 oldValue 的问题

这里写法上和之前有点差异,第一个参数返回的是一个箭头函数.

<template>
  <h2>一个人的信息</h2>
  <div>{{ person.name }}</div>
  <div>{{ person.age }}</div>
  <div>{{ person.a.b.c }}</div>
  <button @click="person.name = 'lyj'">修改姓名</button>
  <button @click="person.age += 1">修改年龄</button>
  <button @click="person.a.b.c += 100">修改a.b.c</button>
</template>

<script>
import { reactive, ref, watch } from "vue";
export default {
  name: "App",
  setup() {
    let person = reactive({
      name: "cyk",
      age: 18,
      a: {
        b: {
          c: 666,
        },
      },
    });

    //情况四
    watch(
      () => person.name,
      (newValue, oldValue) => {
        console.log("person 的 name 变化了", newValue, oldValue);
      }
    );

    return {
      person,
    };
  },
};
</script>

点就 修改姓名 按钮,效果如下: 

 

e)监视 reactive 所定义的一个响应式数据中的某些属性(这种方式可以用来解决监视 reactive 后 oldValue 变化的问题).

<template>
  <h2>一个人的信息</h2>
  <div>{{ person.name }}</div>
  <div>{{ person.age }}</div>
  <div>{{ person.a.b.c }}</div>
  <button @click="person.name = 'lyj'">修改姓名</button>
  <button @click="person.age += 1">修改年龄</button>
  <button @click="person.a.b.c += 100">修改a.b.c</button>
</template>

<script>
import { reactive, ref, watch } from "vue";
export default {
  name: "App",
  setup() {
    let person = reactive({
      name: "cyk",
      age: 18,
      a: {
        b: {
          c: 666,
        },
      },
    });

    //情况五
    watch([() => person.name, () => person.age], (newValue, oldValue) => {
      console.log("person 的 name 或 age 变化了", newValue, oldValue);
    });

    return {
      person,
    };
  },
};
</script>

依次点击 修改姓名 和 修改年龄,效果如下:

f)特殊情况:当监视的是 reactive 定义的对象中的某个属性对象或者当前对象,并且第一个参数返回的是 回调方法,deep也会生效,默认非深层监视.

1.2、watchEffect 函数

watchEffect 的参数就是一个回调.

不用指明监视的是哪个属性,只要监视的回调中用到哪个属性发生变化了,就会重新执行回调(挂载的时候也会执行一次).

<template>
  <h2>一个人的信息</h2>
  <div>{{ person.name }}</div>
  <div>{{ person.age }}</div>
  <div>{{ person.a.b.c }}</div>
  <button @click="person.name = 'lyj'">修改姓名</button>
  <button @click="person.age += 1">修改年龄</button>
  <button @click="person.a.b.c += 100">修改a.b.c</button>
</template>

<script>
import { reactive, watchEffect } from "vue";
export default {
  name: "App",
  setup() {
    let person = reactive({
      name: "cyk",
      age: 18,
      a: {
        b: {
          c: 666,
        },
      },
    });

    watchEffect(() => {
      const test1 = person.name;
      const test2 = person.a.b.c;
      console.log("watchEffect 回调执行了");
    });

    return {
      person,
    };
  },
};
</script>

刚开始组件挂载的时候会执行一次,之后分别点击 修改姓名 和 修改 a.b.c ,又会执行两次,效果如下: 

Ps:默认 deep: false,因此如果 watchEffect 中使用 person.a 的话,修改 person.a.b.c 是不会重新执行回调的.

1.3、toRef 和 toRefs

1.3.1、toRef

将指定的属性通过 toRef 就可以创建一个 ref 对象.

通俗来讲,是对源对象的属性的浅拷贝,并且将源对象对应的属性改成响应式的.

为什么要使用它?例如以下场景:

    let person = reactive({
      name: "cyk",
      age: 18,
      a: {
        b: {
          c: 666,
        },
      },
    });

a)要给模板中展示  person 的所有属性很麻烦,每次都要 person. 的方式才能获取到对应的属性,因此可能就有人会这样操作:

    let person = reactive({
      name: "cyk",
      age: 18,
      a: {
        b: {
          c: 666,
        },
      },
    });
    return {
      person,
      name: person.name, //模板中可以直接使用 name 表示 person.name
      age: person.age, //同理
    };

b)但是上述这种方式返回的数据不是响应式的呀,因此,就有人想到了以下方式

    let person = reactive({
      name: "cyk",
      age: 18,
      a: {
        b: {
          c: 666,
        },
      },
    });
    return {
      person,
      name: ref(person.name), //模板中可以直接使用 name 表示 person.name
      age: ref(person.age), //同理
    };

c)虽然实现了响应式,但是这相当于是重新创建了一个新的 ref 对象,对这些数据的修改不会影响源数据,因此就需要使用 toRef 了~

    let person = reactive({
      name: "cyk",
      age: 18,
      a: {
        b: {
          c: 666,
        },
      },
    });
    return {
      person,
      name: toRef(person, "name"), //模板中可以直接使用 name 表示 person.name
      age: toRef(person, "age"), //同理
    };

1.3.2、toRefs

和 toRef 的功能一致,但是它可以直接将一个对象中的所有属性都变成响应式的,语法:toRefs(person).

    return {
      ...toRefs(person),
    };

 

1.4、vue3  的声明周期

a)vue3 中可以继续使用 vue2 中的生命周期钩子,但有两个被更名.

  • beforeDestory 改名为 beforeUnmount.
  • destroyed 改名为 unmounted.

b)vue3 中也提供了 Composition API 形式的生命周期钩子,与 vue2 中的钩子对应关系如下:

案例如下:

App 父组件定义如下

<template>
  <button @click="isShowUser = !isShowUser">切换隐藏/显示</button>
  <User v-if="isShowUser" />
</template>

<script>
import { ref } from "vue";
import User from "./views/User.vue";
export default {
  name: "App",
  components: { User },
  setup() {
    let isShowUser = ref(true);
    return {
      isShowUser,
    };
  },
};
</script>

 User 子组件如下:

<template>
  <h2>求和: {{ sum }}</h2>
  <button @click="sum++">点我 + 1</button>
</template>

<script>
import {
  ref,
  onBeforeMount,
  onBeforeUnmount,
  onBeforeUpdate,
  onMounted,
  onUnmounted,
  onUpdated,
} from "vue";
export default {
  name: "User",
  setup() {
    let sum = ref(0);

    // vue3 中可以通过组合式 API 的形式取使用声明周期的钩子
    onBeforeMount(() => {
      console.log("-------onBeforeMount-------");
    });
    onMounted(() => {
      console.log("-------onMounted-------");
    });
    onBeforeUpdate(() => {
      console.log("-------onBeforeUpdate-------");
    });
    onUpdated(() => {
      console.log("-------onUpdated-------");
    });
    onBeforeUnmount(() => {
      console.log("--------onBeforeUnmount------");
    });
    onUnmounted(() => {
      console.log("--------onUnmounted------");
    });

    return {
      sum,
    };
  },
};
</script>

使用效果如下: 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机设计大赛 深度学习 YOLO 实现车牌识别算法

文章目录 0 前言1 课题介绍2 算法简介2.1网络架构 3 数据准备4 模型训练5 实现效果5.1 图片识别效果5.2视频识别效果 6 部分关键代码7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于yolov5的深度学习车牌识别系统实现 该项目较…

platform总线

1、平台总线模型 平台总线模型是Linux系统虚拟出来的总线&#xff0c;而I2C、SPI等物理总线是真实存在的。 平台总线模型将一个驱动分成两个部分&#xff0c;分别是device.c和driver.c&#xff0c;分别用来描述硬件信息和控制硬件。 平台总线通过字符串比较&#xff0c;将name…

MySQL数据库①_MySQL入门(概念+使用)

目录 1. 数据库的概念 1.1 数据库的存储介质 1.2 主流数据库 2. MySQL的基本使用 2.1 链接数据库 2.2 服务器管理 2.3 数据库&#xff0c;服务器和表关系 2.4 简单MySQL语句 3. MySQL架构 4. SQL分类 5. 存储引擎 本篇完。 1. 数据库的概念 数据库是按照数据结构来…

蓝桥杯备战——12.PCF8591芯片的使用

目录 1.芯片简介2.读写时序3.控制字4.代码封装库5.原理图分析6.使用示例 1.芯片简介 截取自NXP的PCF8591芯片数据手册&#xff0c;我把重点关注部分划出来了&#xff0c;请务必自行阅读一遍数据手册&#xff01; 2.读写时序 ①器件地址&#xff1a; Bit0决定是读还是写操作&…

阳光倒灌光催化太阳光(太阳能)模拟器

太阳光&#xff08;太阳能&#xff09;模拟器是一种模拟太阳光照射的设备。由于太阳模拟器本身体积较小&#xff0c;测试过程不受环境、气候、时间等因素影响&#xff0c;从而避免了室外测量的各种因素限制&#xff0c;广泛应用于太阳能电池特性测试&#xff0c;光电材料特性测…

数学建模比赛期间,网上的各种思路靠谱吗

美赛第二天&#xff0c;很多人已经撑不住了。 从昨天起网上就那么多“思路”、“指导”、“代做”、“成品论文”&#xff0c;有免费的&#xff0c;也有收钱的。 有人说那些思路都是滥竽充数&#xff0c;纯坑钱浪费时间 有人说自己啥都不会&#xff0c;看那些思路就有启发 有…

一些你可能用到的函数和头文件

对于排序想必大家应该挺熟悉的&#xff0c;如果要是给一连串打乱的整数让你由小到大排序&#xff0c;常见的方法有冒泡排序法和选择排序法等&#xff0c;今天我就给大家介绍一个十分好用的方法&#xff0c;就是使用 sort 函数来进行快排。 sort 函数是位于头文件 #include <…

正点原子--STM32定时器学习笔记(2)

书接上文&#xff0c;本篇是对基本定时器实验部分进行的总结~ 实验目标&#xff1a;通过TIM6基本定时器定时500ms&#xff0c;让LED0每隔500ms闪烁。 解决思路&#xff1a;使用定时器6&#xff0c;实现500ms产生一次定时器更新中断&#xff0c;在中断里执行“翻转LED0”。 定时…

其他发现:开源数据可视化分析工具DataEase介绍文档

一、 简介 DataEase 是开源的数据可视化分析工具&#xff0c;帮助用户快速分析数据并洞察业务趋势&#xff0c;从而实现业务的改进与优化。DataEase 支持丰富的数据源连接&#xff0c;能够通过拖拉拽方式快速制作图表&#xff0c;并可以方便地与他人分享。 二、 优势 1、 开…

MySQL-----DML基础操作

DML语句 DML英文全称是Data Manipulation Language(数据操作语言)&#xff0c;用来对数据库中表的数据记录进行增删改操作。 ▶ 添加数据(INSERT) 【语法】 1. 给指定字段添加数据 INSERTO 表名 (字段名1&#xff0c;字段名2,...) VALUES (值1&#xff0c;值2,...); 2.给全…

npm install一直报错 failed, reason: certificate has expired

刚开始我以为是taobao镜像源的问题&#xff0c;所以我把npm的地址切换成了 https://resgistry.npmjs.org/ &#xff0c;发现还是不行。 问题解决&#xff1a; npm config set strict-ssl false 执行上面命令之后&#xff0c;npm install 成功

如何搭建私有云盘SeaFile并实现远程访问本地文件资料

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-hsDnDEybLME85dTx {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

有限合伙协议书(模板)上

第一章 合伙的目的和合伙经营范围 第一条 合伙目的&#xff1a;为了适应市场经济的发展&#xff0c;满足市场需求&#xff0c;按照《合伙企业法》规范企业行为&#xff0c;合伙人本着公平、平等、互利的原则&#xff0c;成立 聚源企业管理中心&#xff08;有限合伙&am…

React 面试题

1、组件通信的方式 父组件传子组件&#xff1a;通过props 的方式 子组件传父组件&#xff1a;父组件将自身函数传入&#xff0c;子组件调用该函数&#xff0c;父组件在函数中拿到子组件传递的数据 兄弟组件通信&#xff1a;找到共同的父节点&#xff0c;用父节点转发进行通信 …

三层交换组网实验(思科)

一&#xff0c;技术简介 三层交换技术的出现&#xff0c;解决子网必须依赖路由器进行管理的问题&#xff0c;解决传统路由器低速、复杂所造成的网络瓶颈问题。一个具有三层交换功能的设备可简单理解为&#xff1a;一个带有第三层路由功能的第二层交换机。 二&#xff0c;实验目…

yum命令下载出现Failed to synchronize cache for repo ‘AppStream‘, ignoring this repo.

修改下面的配置文件 问题&#xff1a; cd /etc/yum.repos.d 修改下面四个文件 vim CentOS-Base.repo vim CentOS-AppStream.repo vim CentOS-Extras.repo vim CentOS-PowerTools.repo测试yum是否正常 yum -y install wget

备战蓝桥杯---搜索(DFS基础1)

何为深搜&#xff1f; 即不撞南墙不罢休。 话不多说&#xff0c;直接看题&#xff1a; 我们可以把这看成深搜的模板题&#xff0c;下面是AC代码&#xff1a; #include<bits/stdc.h> using namespace std; int a[15];//存值并输出 int vis[15]; int n18; void dfs(int …

【Git】04 .git目录

文章目录 一、.git目录二、切换分支三、仓库配置信息四、引用五、对象六、总结 一、.git目录 ls -a .git/./ COMMIT_EDITMSG description hooks/ info/ objects/ ../ config HEAD index logs/ refs/二、切换分支 cat .git/HEAD #…

2024年美国大学生数学建模比赛MCM问题B:搜索潜水器-思路解析与代码解答

2024 MCM Problem B Searching for Submersibles 一、题目翻译 背景&#xff1a; 总部位于希腊的小型海上巡航潜艇&#xff08;MCMS&#xff09;公司&#xff0c;制造能够将人类运送到海洋最深处的潜水器。潜水器被移动到该位置&#xff0c;并不受主船的束缚。MCMS现在希望用…

跟着pink老师前端入门教程-day17

2、CSS3 动画 动画&#xff08;animation&#xff09;是CSS3中就要有颠覆性的特征之一&#xff0c;可通过设置多个节点来精确控制一个或一组动画&#xff0c;常用来实现复杂的动画效果 相比较过渡&#xff0c;动画可以实现更多变化&#xff0c;更多控制&#xff0c;连续自动播…