手摸手带你初探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
手摸手带你初探Vue 3.0的更多相关文章
- 【转】手摸手,带你用vue撸后台 系列二(登录权限篇)
前言 拖更有点严重,过了半个月才写了第二篇教程.无奈自己是一个业务猿,每天被我司的产品虐的死去活来,之前又病了一下休息了几天,大家见谅. 进入正题,做后台项目区别于做其它的项目,权限验证与安全性是非常 ...
- 【转】手摸手,带你用vue撸后台 系列三(实战篇)
前言 在前面两篇文章中已经把基础工作环境构建完成,也已经把后台核心的登录和权限完成了,现在手摸手,一起进入实操. Element 去年十月份开始用vue做管理后台的时候毫不犹豫的就选择了Elemen, ...
- 【转】手摸手,带你用vue撸后台 系列四(vueAdmin 一个极简的后台基础模板)
前言 做这个 vueAdmin-template 的主要原因是: vue-element-admin 这个项目的初衷是一个vue的管理后台集成方案,把平时用到的一些组件或者经验分享给大家,同时它也在不 ...
- 【转】手摸手,带你用vue撸后台 系列一
前言 说好的教程终于来了,第一篇文章主要来说一说在开始写业务代码前的一些准备工作吧,但这里不会教你webpack的基础配置,热更新怎么做,webpack速度优化等等,有需求的请自行google. 目录 ...
- 手摸手带你理解Vue的Computed原理
前言 computed 在 Vue 中是很常用的属性配置,它能够随着依赖属性的变化而变化,为我们带来很大便利.那么本文就来带大家全面理解 computed 的内部原理以及工作流程. 在这之前,希望你能 ...
- 手摸手带你理解Vue的Watch原理
前言 watch 是由用户定义的数据监听,当监听的属性发生改变就会触发回调,这项配置在业务中是很常用.在面试时,也是必问知识点,一般会用作和 computed 进行比较. 那么本文就来带大家从源码理解 ...
- 【手摸手,带你搭建前后端分离商城系统】01 搭建基本代码框架、生成一个基本API
[手摸手,带你搭建前后端分离商城系统]01 搭建基本代码框架.生成一个基本API 通过本教程的学习,将带你从零搭建一个商城系统. 当然,这个商城涵盖了很多流行的知识点和技术核心 我可以学习到什么? S ...
- 【手摸手,带你搭建前后端分离商城系统】02 VUE-CLI 脚手架生成基本项目,axios配置请求、解决跨域问题
[手摸手,带你搭建前后端分离商城系统]02 VUE-CLI 脚手架生成基本项目,axios配置请求.解决跨域问题. 回顾一下上一节我们学习到的内容.已经将一个 usm_admin 后台用户 表的基本增 ...
- 【手摸手,带你搭建前后端分离商城系统】03 整合Spring Security token 实现方案,完成主业务登录
[手摸手,带你搭建前后端分离商城系统]03 整合Spring Security token 实现方案,完成主业务登录 上节里面,我们已经将基本的前端 VUE + Element UI 整合到了一起.并 ...
- 原创 | 手摸手带您学会 Elasticsearch 单机、集群、插件安装(图文教程)
欢迎关注笔者的公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site/ ...
随机推荐
- DeFi-DEX-借贷
不知道为什么上课的笔记没保存上55555 看看ppt和视频吧(
- OpenAI-GPT
操作系统:CentOS 7.6 安装依赖软件 进入 root 账号: sudo -i 安装部署 ChatGPT 必备的软件,并且启动 nginx : yum install git nginx -y ...
- Consistency Models终结扩散模型
最近看到一篇论文,觉得特别有意思,并且在学术界引起了不小的动静,他就是一致性模型,据说图像生成效果快.质量高,并且还可以实现零样本图像编辑,即不进行一些视觉任务训练,可以实现图像超分.修复.上色等功能 ...
- 一站式统一返回值封装、异常处理、异常错误码解决方案—最强的Sping Boot接口优雅响应处理器
作者:京东物流 覃玉杰 1. 简介 Graceful Response是一个Spring Boot体系下的优雅响应处理器,提供一站式统一返回值封装.异常处理.异常错误码等功能. 使用Graceful ...
- ReactHub:我用 ChatGPT 搞了一个 React 的资源导航网站,谁有我用心啊!
大家好,我是DOM哥. 图谱年年有,今年我来盘! 之前已经盘完了 Vue 的技术图谱,今天来盘 React 的. 我用 ChatGPT 开发了一个 React 的资源导航网站. 不管你是资深 Reac ...
- 2023-04-25:给定两个长度为N的数组,a[]和b[] 也就是对于每个位置i来说,有a[i]和b[i]两个属性 i a[i] b[i] j a[j] b[j] 现在想为了i,选一个最
2023-04-25:给定两个长度为N的数组,a[]和b[] 也就是对于每个位置i来说,有a[i]和b[i]两个属性 i a[i] b[i] j a[j] b[j] 现在想为了i,选一个最好的j位置, ...
- 2021-11-02:生命游戏。根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个
2021-11-02:生命游戏.根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机.给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个 ...
- web自动化05-鼠标操作
鼠标操作方法 1.常见的鼠标操作 点击.右击.双击.悬停.拖拽等 2.selenium中的封装鼠标操作 说明:在Selenium中将操作鼠标的方法封装在ActionChains类中 ...
- odoo开发教程九:Odoo10 API
一:纪录集API model中的数据是以集合的形式使用的,因此可以使用集合运算来操作. 集合运算符 record in set返回record是否在set中,record须为单条记录,record n ...
- List的拆分的几种方式
开发中我们可能会遇到一个大的集合,然后我们需要对集合进行拆分,然后再对拆分的集合进行相关的操作.当然我们可以自己写一个拆分的方法,我自己写过用了不少代码,但是感觉还不是很好,最近看了不少工具才发现很多 ...