手把手带你初探Vue 3.0 | 京东物流技术团队
1 前言
距离Vue 3.0正式发布已经过去一段时间了,2月7日Vue团队正式宣布Vue 3正式成为新的默认版本。最近接触的新项目也使用Vue 3.0来开发,因此有必要对它进行一波总结和学习。
2 简介
在最开始的时候,Vue仅仅是一个运行时库。但经过多年的发展,它已经逐渐变成了一台包含许多子项目的框架。Vue的核心库只关注图层,不仅易于上手,还便于与第三方库或既有项目整合。那么Vue 3.0带来了哪些新的表现呢?
- 重写了虚拟Dom
- 编译模板的优化
- 更高效的组件初始化
- SSR速度提高了2~3倍
- 更新性能提高了1.3~2倍
- 看起来Vue 3相比于2性能上有了很大的提升,作为终端用户的我们,还是来看看代码是如何实现的吧。
3 新的特性
3.1 组合式API
Vue 2中采用的是Options API(选项式API),即在data、methods、computed、watch中分别写入代码,如果我们需要增加一个逻辑,就需要在这些选项中反复横跳,导致组件难以理解和阅读。Vue 3新增了setup选项,它是组合式API的入口。它将同一个逻辑关注点相关代码收集在一起,这样我们需要维护一个功能点的时候,就不需要去关心其他的逻辑。
举个例子
<template> <div>{{number}}</div> <button @click="add">Add</button> </template> <script> import { ref } from 'vue' export default { setup () { const number = ref(0) //ref()函数使变量变为响应式 const add = () => { number.value++ //使用ref创建的响应式变量需要加.value } return { //返回的变量和方法可以在模板中直接使用 number, add } } } </script>
这看起来不就是把data、methods中的内容都放到setup里了吗,也没多大区别啊?其实,我们还可以把setup里面的内容分割成一个个独立的函数,每个函数负责独立的功能。这样,我们就可以在不同组件中进行复用,简洁代码,这才是组合式API的强大之处。
3.2 响应式API
3.2.1 ref
在上面的代码中我们使用了ref创建了响应式对象,它接受js基本类型或引用类型作为参数,返回的就是一个只包含名为value参数的RefImp对象。在setup函数中如果我们要使用该响应式对象,就需要加上.value。但是在模板中被渲染时,自动展开内部的值,因此不需要在模板中追加.value。
ref常用于基础类型,如果ref传入对象,其内部会转换为reactive进行处理。
import { ref } from "vue"; const str = ref(""); const male = ref(true); str.value = "new val"; console.log(str.value); //new val male.value = false; console.log(male.value) //fals
3.2.2 reactive
reactive函数只接收object和array等复杂数据类型,它会返回一个proxy对象。reactive可以深层次递归,也就是如果发现展开的属性值是引用类型的而且被引用,还会用reactive递归处理。而且属性是可以被修改的。 proxy是es6中用于创建一个对象的代理函数,可以实现对目标对象的增删改查等基本操作的拦截和自定义。
const p=new Proxy(target,handler) //target是proxy包装的目标对象,handler是一个以函数作为属性的对象
简单模拟实现reactive实现响应式:
const obj={a:1,b:2} const p=new Proxy(obj,{ get(target,key){ console.log(`p的${key}属性被访问了!`) return Reflect.get(target,key) }, set(target,key,value){ console.log(`p的${key}属性被修改了!`) return Reflect.set(target,key,value) }, deleteProperty(target,key){ console.log(`p的${key}属性被删除了!`) return Reflect.deleteProperty(target,key) } })
3.2.3 toRefs
通过上面的介绍我们已经知道了ref通常用来创建基础类型数据的双向绑定,reactive通常用来创建引用数据类型的双向绑定。除此之外,ref也可以创建复杂类型的双向绑定,而reactive不能代理基础类型。我们来看一个例子:
<template> <div>{{user.name}}</div> <div>{{user.age}}</div> <div>{{user.sex}}</div> <button @click="changeInfo">更改个人信息</button> </template> <script> import { ref } from 'vue' export default { setup () { const user = ref({name:'张三',age:'18',sex:'男'}) const changeInfo = () => { user.name.value='李四' user.age=20 user.sex='女' } return { user } } } </script>
上面的代码中我们绑定到页面使用的是user.name,user.age,这样写感觉很繁琐,那能通过解构解构user然后在模板中直接使用吗?答案是不能的,这样做会使user丢失掉响应式。但是通过使用toRefs,就可以直接使用解构后的数据了。 toRefs 用于将一个 reactive 对象转化为属性全部为 ref 对象的普通对象。具体使用方式如下:
<template> <div>{{name}}</div> <div>{{age}}</div> <div>{{sex}}</div> <button @click="changeInfo">更改个人信息</button> </template> <script> import { ref } from 'vue' export default { setup () { const user = ref({name:'张三',age:'18',sex:'男'}) const changeInfo = () => { user.name.value='李四' user.age=20 user.sex='女' } return { ...toRefs(user) //使用toRefs } } }
3.3 响应式侦听
watch 函数用来侦听特定的数据源,并在回调函数中执行副作用。默认情况是惰性的,也就是说仅在侦听的源数据变更时才执行回调。
watch(source,callback,[options])
- source:可以支持 string,Object,Function,Array; 用于指定要侦听的响应式变量
- callback:执行的回调函数
- options:可选项,支持 deep、immediate 和 flush
监听单个数据源的用法:
import { reactive, ref, watch } from "vue"; const state = reactive({ number:0, id:'01' }); //侦听reative对象 watch( () => state.number, (newvalue, oldvalue) => { console.log(newvalue, oldvalue); //1 0 } ); state.number++; const count = ref(0); //侦听ref对象 watch(count, (count, prevCount) => { console.log(count, prevCount, "watch"); //2 0 }); count.value = 2
监听多个数据源的用法:
import { reactive, ref, watch } from "vue"; const state = reactive({ number:0, id:'01' }); const count = ref(0); watch([count,()=>{state.number}],([curcount,precount],[curnumber,prenumber])=>{ console.log(curcount,precount) //2 0 console.log(curnumber,prenumber) //1 0 }) state.number++ count.value=2
对于多层嵌套的引用对象,可以使用{deep:true}开启深度监听。否则仅能监听到外层数据变化。前面提到,默认清空下watch的回调函数是惰性的,只有当监听数据变化时才会执行。当配置{immediate: true}时,可以立即执行回调函数。
3.4 生命周期
在Vue2中有8个生命周期函数:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
在vue3中,新增了一个setup生命周期函数,setup执行的时机是在beforeCreate生命函数之前执行,因此在这个函数中是不能通过this来获取实例的;同时为了命名的统一,将beforeDestroy改名为beforeUnmount,destroyed改名为unmounted,因此vue3有以下生命周期函数:
- beforeCreate -> 不需要
- created -> 不需要
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeUnmount -> onBeforeUnmount
- unmounted -> onUnmounted
- errorCaptured -> onErrorCaptured
- renderTracked -> onRenderTracked
- renderTriggered -> onRenderTriggered
4 总结
通过对以上知识的总结对Vue 3有了进一步的认识,基本能够满足项目开发。更多的改动大家可以自行查阅官方文档和阅读源码,相信Vue 3能给我们带来更多新的体验。
作者:京东物流 颜之婷
来源:京东云开发者社区 自猿其说Tech

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
CRM系统化整合从N-1做减法实践 | 京东物流技术团队
1 背景 京销易系统已经接入大网、KA以及云仓三个条线商机,每个条线商机规则差异比较大,当前现状是独立实现三套系统分别做支撑。 2 目标 2022年下半年CRM目标是完成9个新条线业务接入,完成销售过程线上化,实现销售规则统一。 3 问题 前端实现数据存储与逻辑代码耦合一起,无法复用,无法扩展,组件化拆分难度大。 组件拆分颗粒度较大,业务功能抽象不充分,缺乏复用性。 代码重复编写,相似功能冗余严重,开发和维护效率低。 代码版本多,接口不统一,开发、运维成本高,难扩展。 每个条线阶段、条线内每个商机阶段推进规则都是通过代码单独实现,开发、维护成本高,规则调整都需要代码调整并上线,时效性低,同时阶段规则维护在代码中,无法直观呈现和规则统一收口,运维难度大。 4 实现 4.1 方案调研 方案调研阶段,针对业务场景,多次组会对于底层实现方案进行充分讨论,列举每个方案优劣势,选择最适合当前业务场景的解决方案,最终选择上图的框架升级方案。 4.2 方案设计 4.2.1 设计思路 快速实现相似业务,减少相似代码,通过前端组件化、后端服务标准化、商机阶段配置化技术手段,支持各条线快速复用和灵活扩展。 ...
- 下一篇
不止工具:音视频开发「利器」的新机遇
Boxing的制胜关键是快、准、稳,与“音视频开发”有异曲同工之妙。 数字化浪潮席卷、视频化形态加速、终端性能挑战加剧、端侧算力遭遇瓶颈...... 是否存在一种可能性,让所有企业从复杂的音视频开发工程中抽身,重新回归业务本身? 一站式音视频服务如何获取?冗长繁琐的SDK接入流程怎样简化?能否在降低开发门槛的同时,依然掌握主动权? 场景智能,会是下一个风口吗? 面向场景建设音视频技术能力,如何释放更多“数字生产力”? 应对多样化,音视频终端套件如何满足“千行千面”? 本文由IMMENSE、「阿里云视频云」媒体服务应用端负责人洪炳峰和LiveVideoStack策划、采访而成。 01 掀开数字化浪潮的一面 当谈论行业数字化时,我们在谈论什么? 过去几年中,行业数字化建设如火如荼。 据权威数据,65%的行业数字化信息来自视频,另外,还包含5%的音频信息。不得不说,音视频技术对于行业数字化来说,至关重要,而音视频数字化也正是行业数字化的先行之态。 昭然可见,承载于云计算的音视频技术,正向各行各业加速渗透,从消费互联网,转向教育、医疗、金融、零售等传统行业,产业互联网纷纷掀起音视频数字化风...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- Linux系统CentOS6、CentOS7手动修改IP地址
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题