一个 Java 猿眼中 Vue3 和 Vue2 的差异
随着 TienChin 项目视频的录制,松哥终于也要静下心来,认真捋一捋 Vue3 中的各种新特性了,然后再和小伙伴们进行分享,其实 Vue3 中还是带来了很多新鲜的玩意,今天我们就不卷 Java 了,来卷卷前端。
以下内容是一个 Java 猿对 Vue3 的理解,主要是应用层面上,如果有专业的前端小伙伴,请轻拍。
1. script 写法
进入到 Vue3 时代,最明显的感受就是在一个 .vue 文件中,script 标签的写法大变样了。以前在 Vue2 中,我们都是这样写的:
<script>export default {name: "SysHr",data() {return {//}},mounted() {//},methods: {deleteHr(hr) {//},doSearch() {//}}}
</script>
不过到了 Vue3 里边,这个写法变了,变成下面这样了:
<template><div><div>{{a}}</div><div>{{result}}</div><button @click="btnClick">clickMe</button></div>
</template>
<script>import {ref} from 'vue';import {onMounted,computed} from 'vue'export default {name: "MyVue01",setup() {const a = ref(1);const btnClick=()=>{a.value++;}onMounted(() => {a.value++;});const result = computed(()=>{return Date.now();});return {a,btnClick,result}}}
</script>
先从大的方面来看,细节实现咱们后面再细聊。
大的方面,就是在这个 export default 中,以后就只有两个元素了,name 和 setup,我们以前的各种方法定义、生命周期函数、计算属性等等,都写在 setup 中,并且需要在 setup 中返回,setup 中返回了什么,上面的 template 中就能用什么。
这种写法稍微有点费事,所以还有一种简化的写法,像下面这样:
<template><div><div>{{a}}</div><div>{{result}}</div><button @click="btnClick">clickMe</button></div>
</template><script setup>import {ref} from 'vue';import {onMounted, computed} from 'vue'const a = ref(1);const btnClick = () => {a.value++;}onMounted(() => {a.value++;});const result = computed(() => {return Date.now();});
</script>
这种写法就是直接在 script 标签中加入 setup,然后在 script 标签中该怎么定义就怎么定义,也不用 return 了。这个场景,又有点 jQuery 的感觉了。
上面这个实现里有几个细节,我们再来详细说说。
2. 生命周期
首先就是生命周期函数的写法。
以前 Vue2 里的写法有一个专业名词叫做 options API,现在在 Vue3 里也有一个专业名词叫做 composition API。在 Vue3 中,这些对应的生命周期函数都要先从 vue 中导出,然后调用并传入一个回调函数,像我们上一小节那样写。
下图这张表格展示了 options API 和 composition API 的一一对应关系:
options API | composition API |
---|---|
beforeCreate | Not Needed |
created | Not Needed |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
activated | onActivated |
deactivated | onDeactivated |
想用哪个生命周期函数,就从 vue 中导出这个函数,然后传入回一个回调就可以使用了。例如第一小节中松哥给大家举的 onMounted 的用法。
3. 计算属性
除了生命周期函数,计算属性、watch 监听等等,用法也和生命周期函数类似,需要先从 vue 中导出,导出之后,也是传入一个回调函数就可以使用了。上文有例子,我就不再啰嗦了。
像 watch 的监控,写法如下:
<script>import {ref} from 'vue';import {onMounted,computed,watch} from 'vue'export default {name: "MyVue01",setup() {const a = ref(1);const btnClick=()=>{a.value++;}onMounted(() => {a.value++;});const result = computed(()=>{return Date.now();});watch(a,(value,oldValue)=>{console.log("value", value);console.log("oldValue", oldValue);})return {a,btnClick,result}}}
</script>
导入 watch 之后,然后直接使用即可。
4. ref 于 reactive
上面的例子中还有一个 ref,这个玩意也需要跟大家介绍下。
在 Vue2 里边,如果我们想要定义响应式数据,一般都是写在 data 函数中的,类似下面这样:
<script>export default {name: "SysHr",data() {return {keywords: '',hrs: [],selectedRoles: [],allroles: []}}}
</script>
但是在 Vue3 里边,你已经看不到 data 函数了,那怎么定义响应式数据呢?就是通过 ref 或者 reactive 来定义了。
在第一小节中,我们就是通过 ref 定义了一个名为 a 的响应式变量。
这个 a 在 script 中写的时候,有一个 value 属性,不过在 HTML 中引用的时候,是没有 value 的,可千万别写成了 {{a.value}}
,我们再来回顾下上文的案例:
<template><div><div>{{a}}</div><button @click="btnClick">clickMe</button></div>
</template><script>import {ref} from 'vue';export default {name: "MyVue04",setup() {const a = ref(1);const btnClick=()=>{a.value++;}return {a,btnClick}}}
</script>
现在就是通过这样的方式来定义响应式对象,修改值的时候,需要用 a.value
,但是真正的上面的 template 节点中访问的时候是不需要 value 的(注意,函数也得返回后才能在页面中使用)。
和 Vue2 相比,这种写法有一个很大的好处就是在方法中引用的时候不用再写 this 了。
ref 一般用来定义原始数据类型,像 String、Number、BigInt、Boolean、Symbol、Null、Undefined 这些。
如果你想定义对象,那么可以使用 reactive 来定义,如下:
<template><div><div>{{a}}</div><button @click="btnClick">clickMe</button><div>{{book.name}}</div><div>{{book.author}}</div></div>
</template><script>import {ref, reactive} from 'vue';export default {name: "MyVue04",setup() {const a = ref(1);const book = reactive({name: "三国演义",author: "罗贯中"});const btnClick = () => {a.value++;}return {a, btnClick,book}}}
</script>
这里定义了 book 对象,book 对象中包含了 name 和 author 两个属性。
有的时候,你可能批量把数据定义好了,但是在访问的时候却希望直接访问,那么我们可以使用数据展开,像下面这样:
<template><div><div>{{a}}</div><button @click="btnClick">clickMe</button><div>{{name}}</div><div>{{author}}</div></div>
</template><script>import {ref, reactive} from 'vue';export default {name: "MyVue04",setup() {const a = ref(1);const book = reactive({name: "三国演义",author: "罗贯中"});const btnClick = () => {a.value++;}return {a, btnClick,...book}}}
</script>
这样,在上面访问的时候,就可以直接访问 name 和 author 两个属性了,就不用添加 book 前缀了。
不过!!!
这种写法其实有一个小坑。
比如我再添加一个按钮,如下:
<template><div><div>{{a}}</div><button @click="btnClick">clickMe</button><div>{{name}}</div><div>{{author}}</div><button @click="updateBook">更新图书信息</button></div>
</template><script>import {ref, reactive} from 'vue';export default {name: "MyVue04",setup() {const a = ref(1);const book = reactive({name: "三国演义",author: "罗贯中"});const btnClick = () => {a.value++;}const updateBook=()=>{book.name = '123';}return {a, btnClick,...book,updateBook}}}
</script>
这个时候点击更新按钮,你会发现没反应!因为用了数据展开之后,响应式就失效了。所以,对于这种展开的数据,应该再用 toRefs 来处理下,如下:
<template><div><div>{{a}}</div><button @click="btnClick">clickMe</button><div>{{name}}</div><div>{{author}}</div><button @click="updateBook">更新图书信息</button></div>
</template><script>import {ref, reactive, toRefs} from 'vue';export default {name: "MyVue04",setup() {const a = ref(1);const book = reactive({name: "三国演义",author: "罗贯中"});const btnClick = () => {a.value++;}const updateBook = () => {book.name = '123';}return {a, btnClick, ...toRefs(book),updateBook}}}
</script>
当然,如果你将 setup 直接写在了 script 标签中,那么可以直接按照如下方式来展开数据:
<template><div><div>{{a}}</div><button @click="btnClick">clickMe</button><div>{{name}}</div><div>{{author}}</div><button @click="updateBook">更新图书信息</button></div>
</template><script setup>import {ref, reactive, toRefs} from 'vue';const a = ref(1);const book = reactive({name: "三国演义",author: "罗贯中"});const btnClick = () => {a.value++;}const updateBook = () => {book.name = '123';}const {name, author} = toRefs(book);
</script>
5. 小结
好啦,今天就和小伙伴们分享了 Vue3 中几个新鲜的玩法~作为我们 TienChin 项目的基础(Vue 基本用法在 vhr 中都已经讲过了,所以这里就不再赘述了),当然,Vue3 和 Vue2 还有其他一些差异,这些我们都将在 TienChin 项目视频中和小伙伴们再仔细分享。
一个 Java 猿眼中 Vue3 和 Vue2 的差异相关推荐
- 一个程序猿眼中的国内主流地图api
在网站或者手机应用中,经常用到地图api.在现在这么激烈的竞争下,各地图服务提供的服务基本都趋于一致了.一个公司推出的新服务,其他公司肯定也会很快的跟进.这样,对于开发者来说,地图api的选择就主要参 ...
- 一个java程序猿之路
第一部分:对于尚未做过Java工作的同学,包括一些在校生以及刚准备转行Java的同学. 一.Java基础 首先去找一个Java的基础教程学一下,这里可以推荐一个地址,或者你也可以参照这个地址上去找相应 ...
- 娱乐弹弹弹——程序猿眼中的女人
程序猿,整天跟操作系统,编程语言,各种打交道,那么程序猿眼中的女人是什么样子的呢? 有程序猿曾经用操作系统形容过各种类型的女人,有程序猿用编程语言描述各种星座的女人. 小编找到了几个版本,请看: 编程 ...
- OSChina 娱乐弹弹弹——程序猿眼中的女人
2019独角兽企业重金招聘Python工程师标准>>> 程序猿,整天跟操作系统,编程语言,各种打交道,那么程序猿眼中的女人是什么样子的呢? 有程序猿曾经用操作系统形容过各种类型的女人 ...
- 推荐一个 Java 接口快速开发框架
欢迎关注方志朋的博客,回复"666"获面试宝典 今天给小伙伴们介绍一个Java接口快速开发框架-magic-api 简介 magic-api 是一个基于 Java 的接口快速开发框 ...
- 一个 Java 对象到底有多大?
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 李小武 来源 | http://blog.li ...
- Java黄金五年——1~5年一个Java程序员从入行到大牛的晋升之路
在程序界流行着一种默认的说法叫"黄金5年",也就是一个程序员从入职的时候算起,前五年的选择直接影响着整个职业生涯中的职业发展方向和薪资走向,如何走好这5年,彻底从一个刚入行的菜鸟蜕 ...
- Android Annotation-让你的代码更加优雅(二)做一个Java诗人(JavaPoet)
上篇回顾 上一篇我们按照思维导图,介绍了注解的基础知识,如何定义一个注解,提示性注解,运行时注解的写法和用法.没有看过第一篇,又对注解知识相对陌生的同学,建议先食用第一篇.本篇将重点介绍编译期注解,自 ...
- 连载《一个程序猿的生命周期》-6、自学C++,二级考过后,为工作的机会打下了基础...
一个程序猿的生命周期 微信平台 口 号:职业交流,职业规划:面对现实,用心去交流.感悟. 公众号:iterlifetime 百木-ITer职业交流奋斗 群:141588103 微 博:h ...
最新文章
- 编写 if 时不带 else,你的代码会更好!
- 数据库Sharding的基本思想和切分策略
- [ADB]ADB(Android Debug Bridge)简介及基础(不包含命令)
- 不要再问我跨域的问题了
- 工程师软技能4:找出你的短板
- 智能会议系统(30)---WebRTC学习之一:开篇
- jpa oracle 传参int类型判空_SQL查询:Oracle、mysql、HQL查询语句差异
- 第三季-第26课-网络并发服务器设计
- 符号回归工具之 geppy: Python中的基因表达编程框架
- 如何快速理解模糊PID算法 ---(一)
- 2020计算机校友会大学排名,2020年校友会大学排名:一个世界一流大学,一个中国一流大学...
- 大数据营销中的尿布和啤酒
- MATLAB(2)--MATLAB矩阵的表示
- 【网红流水线车间】“制造”李佳琦们的神秘组织,到底是怎么让网红火起来的?...
- SRTM数据介绍与下载
- 手把手从零到有的个人网站开发
- 感悟:君子不立于危墙之下
- linux LAMP的作用和现状,lamp简介
- 关于出现error: expected declaration or statement at end of input [solution.c]
- 怎么卸载python3.6_Mac 卸载Python3.6