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.nameage: person.age, //同理};

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

    let person = reactive({name: "cyk",age: 18,a: {b: {c: 666,},},});return {person,name: ref(person.name), //模板中可以直接使用 name 表示 person.nameage: 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.nameage: 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>

使用效果如下: 

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

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

相关文章

Attempt to invoke virtual method ‘-‘ on a null object reference错误总结

Android studio开发 出现这个问题一般是&#xff1a;一个Activity中调用另一个xml布局文件&#xff0c;即非本Activity所绑定的xml布局文件中的控件&#xff0c;这时候就不能直接findViewById&#xff0c;不然会报错指向空对象 LayoutInflater factory LayoutInflater.from(…

【蓝桥杯】环形链表的约瑟夫问题

目录 题目描述&#xff1a; 输入描述&#xff1a; 输出描述&#xff1a; 示例1 解法一&#xff08;C&#xff09;&#xff1a; 解法二&#xff08;Cpp&#xff09;&#xff1a; 正文开始&#xff1a; 题目描述&#xff1a; 据说著名犹太历史学家 Josephus 有过以下故事&a…

Pytest测试用例参数化

pytest.mark.parametrize(参数名1,参数名2...参数n, [(参数名1_data1,参数名2_data1...参数名n_data1),(参数名1_data2,参数名2_data2...参数名n_data2)]) 场景&#xff1a; 定义一个登录函数test_login,传入参数为name,password&#xff0c;需要用多个账号去测试登录功能 # …

[职场] 留学生课程辅导待遇 #媒体#经验分享#其他

留学生课程辅导待遇 留学生课程辅导师需要具备专业知识和良好的沟通技巧&#xff0c;能够全面帮助留学生解决学习和生活方面的问题&#xff0c;提高留学生的学习效果和适应能力。 工作内容&#xff1a; 1.提供学习计划和课程指导&#xff1a;留学生课程辅导师可以帮助留学生…

JAVA方法引用:

方法引用的出现原因在使用Lambda表达式的时候&#xff0c;我们实际上传递进去的代码就是一种解决方案&#xff1a;拿参数做操作那么考虑一种情况&#xff1a;如果我们在Lambda中所指定的操作方案&#xff0c;已经有地方存在相同方案&#xff0c;那是否还有必要再写重复逻辑呢&a…

Go中的并发性介绍

并发是一个很酷的话题&#xff0c;一旦你掌握了它&#xff0c;就会成为一笔巨大的财富。说实话&#xff0c;我一开始很害怕写这篇文章&#xff0c;因为我自己直到最近才对并发性不太适应。我已经掌握了基础知识&#xff0c;所以我想帮助其他初学者学习Go的并发性。这是众多并发…

Java SWT Composite 绘画

Java SWT Composite 绘画 1 Java SWT2 Java 图形框架 AWT、Swing、SWT、JavaFX2.1 Java AWT (Abstract Window Toolkit)2.2 Java Swing2.3 Java SWT (Standard Widget Toolkit)2.4 Java JavaFX 3 比较和总结 1 Java SWT Java SWT&#xff08;Standard Widget Toolkit&#xff…

C++从零开始的打怪升级之路(day30)

这是关于一个普通双非本科大一学生的C的学习记录贴 在此前&#xff0c;我学了一点点C语言还有简单的数据结构&#xff0c;如果有小伙伴想和我一起学习的&#xff0c;可以私信我交流分享学习资料 那么开启正题 今天分享的是关于list的基本函数使用 list是一个双向带头循环的…

02 使用jdk运行第一个java程序:HelloWorld

使用jdk运行第一个java程序 1 HelloWorld小案例1.1 编写流程1.2 错误示例 首先在CMD命令行里面&#xff0c;使用javac xxxx.java&#xff0c; 进行编译&#xff0c;其中会有报错&#xff1b; 然后生成xxxx.class 文件&#xff0c;然后使用java xxxx.class 进行运行。 1 HelloWo…

瑞_23种设计模式_抽象工厂模式

文章目录 1 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;1.1 概念1.2 介绍1.3 小结1.4 结构 2 案例一2.1 案例需求2.2 代码实现 3 案例二3.1 需求3.2 实现 4 总结4.1 抽象工厂模式优缺点4.2 抽象工厂模式使用场景4.3 抽象工厂模式VS工厂方法模式4.4 抽象工厂…

node.js基础--01

Author nodes&#xff1a;&#xff08;题记&#xff09; node.js is an open-source&#xff0c;cross-platform JAVAScript runtime environment。 node.js是一个开源&#xff0c;跨平台的js运行环境 common commands&#xff08;常用指令&#xff09; 1、C: enter hard …

javaScript的序列化与反序列化

render函数的基本实现 javaScript的序列化与反序列化 一&#xff0c;js中的序列化二&#xff0c;序列化三&#xff0c;反序列化四&#xff0c;总结 一&#xff0c;js中的序列化 js中序列化就是对象转换成json格式的字符串&#xff0c;使用JSON对象的stringify方法&#xff0c;…

新书速览|Python数据科学应用从入门到精通

系统教授数据科学与Python实战&#xff0c;涵盖线性回归、逻辑回归、决策树、随机森林、神经网 本书内容 随着数据存储、数据处理等大数据技术的快速发展&#xff0c;数据科学在各行各业得到广泛的应用。数据清洗、特征工程、数据可视化、数据挖掘与建模等已成为高校师生和职场…

Socket.D v2.3.9 发布(增加 node.js server 适配)

Socket.D 是基于"事件"和"语义消息""流"的网络应用层传输协议。有用户说&#xff0c;“Socket.D 之于 Socket&#xff0c;尤如 Vue 之于 Js、Mvc 之于 Http”。支持 tcp, udp, ws, kcp 传输。协议特点可参考《官网介绍》。 pyton 已开发完成&a…

STL——空间配置器

空间配置器是STL六大组件之一&#xff0c;它和其他五个组件相互配合&#xff0c;起着很关键的作用。 容器&#xff1a;各种数据结构、如vector、list、stack、deque、queue、set、map、unordered_map等等算法&#xff1a;各种算法&#xff0c;如sort、serach、copy、erase 提供…

C#用正则表达式验证格式:电话号码、密码、邮编、手机号码、身份证、指定的小数点后位数、有效月、有效日

正则表达式在程序设计中有着重要的位置&#xff0c;经常被用于处理字符串信息。 用Regex类的IsMatch方法&#xff0c;使用正则表达式可以验证电话号码是否合法。 一、涉及到的知识点 Regex类的IsMatch方法用于指示正则表达式使用pattern参数中指定的正则表达式是否在输入字符串…

计算机网络_1.6.2 计算机网络体系结构分层的必要性

1.6.2 计算机网络体系结构分层的必要性 一、五层原理体系结构每层各自主要解决什么问题1、物理层2、数据链路层3、网络层4、运输层5、应用层 二、总结三、练习 笔记来源&#xff1a; B站 《深入浅出计算机网络》课程 本节主要介绍实现计算机网络需要解决哪些问题&#xff1f;以…

这种学习单片机的顺序是否合理?

这种学习单片机的顺序是否合理&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01…

vue3 markdown编辑器推荐(maven-editor vditor tiptap )

最近项目需要用到markdown编辑器&#xff0c;使用了三种 maven-editor (http://www.mavoneditor.com/?spma2c6h.12873639.article-detail.9.aaad62affAKmTV)vditor (https://b3log.org/vditor/demo/index.html?utm_sourceld246.com)tiptap (https://github.com/ueberdosis/t…

随着网络的快速发展,网络安全问题也日益凸显,遇到攻击该如何处理,如何抉择合适的防护方案

DexunCloud 经过研究发现当今世界&#xff0c;随着网络的快速发展&#xff0c;网络安全问题也日益凸显。其中&#xff0c;DDoS&#xff08;分布式拒绝服务&#xff09;攻击被认为是网络安全领域里最为严重的威胁之一。毫无疑问&#xff0c;DDoS攻击不仅可以导致网络服务中断&am…