还不会 Vue3 ?一篇笔记带你快速入门

Vue3简介

面临的问题:随着功能的增长,复杂组件的代码变得难以维护,Vue3 就随之而来,TypeScript 使用的越来越多,Vue3就是 TS 写的所以能够更好的支持 TypeScript

在这里介绍就这么简单

vue2 的绝大多数的特性 在 Vue3 都能使用,毕竟 Vue 是渐进式的

响应式原理进行使用 Proxy 实现,v-model 可以传参了等等新特性

基础工作

使用Vue3的话,那么必须通过使用构建工具创建一个 Vue3 项目

安装 vue-cli

创建一个项目

使用 create 命令行创建 或者 用 ui 可视化创建

大家用 Vue 都用了这么久,我就不一一说怎么去创建了

 当然也可以选择 vite ,vite 创建的速度比 上面的方法快了一些

 

Vue3入门

Composition API

Vue3 提出了 Composition API

在 Vue2.X 我们使用的是 OptionAPI 里面有我们熟悉的 datacomputedmethodswatch...

在 Vue3 中,我们依旧可以使用 OptionAPI当然不建议 和 Vue3 混用

在 Vue2 中,我们实现一个功能得分到不同的地方,把数据放在 data ,computed 方法放在 methods 里面,分开的太散乱了,几个功能还好,几十个上百个,那就有点...

所以 Vue3 提出了 Composition API ,它可以把 一个逻辑的代码都收集在一起 单独写个hook,然后再引入,这样就不到处分布,显得很乱了

Fragment

在 template 中不再需要一个根元素包裹

 

实际上内部会将多个标签包含在一个Fragment虚拟元素中

好处: 减少标签层级, 减小内存占用

script 差异

来看看 script 和 Vue2 的区别

 

  • 可以再 script 使用 ts 只需 设置 lang 即可

  • defineComponent 方法创建一个组件

  • export default 直接导出一个组件

setup

setup 是 Composition API的入口

setup 执行顺序

它在beforeCreate之前执行一次beforeCreate这个钩子 的任务就是初始化,在它之前执行,那么 this 就没有被初始化 this = undefined 这样就不能通过 this 来调用方法 和 获取属性

 

setup 返回值

setup 返回的是一个对象,这个对象的属性会与组件中 data 函数返回的对象进行合并,返回的方法和 methods 合并,合并之后直接可以在模板中使用,如果有重名的情况,会使用 setup 返回的属性方法methods 和 data 能够拿到 setup 中的方法应该进行了合并,反之 setup 不能拿到它们的属性和方法,因为这个时候 this = undefined

Suspense 组件

setup 使用 async/await

我们需要 setup 返回数据那么它肯定就不能使用 async 修饰,这样返回 promise 是我们不想看见情况,如果我们硬要用 async 修饰,我们就得用的在它的父组件外层需要嵌套一个suspense(不确定)内置组件,里面放置一些不确定的操作,比如我们就可以把异步组件放入进去

1.子组件

 

 

2.父组件

 

 

setup 参数

setup(propscontext)

setup 函数中的第一个参数是 props。它接收父组件传递的值,是的就是父子组件信息传递的 props

第二个参数是 context 里面包含3个属性 { attrs, slots, emit },这三个属性大家看名字就应该知道是什么吧 分别对应 this.$attrsthis.$slotsthis.$emit

  • attrs: 除了 props 中的其他属性

  • slots: 父组件传入插槽内容的对象

  • emit: 和用于父子组件通信

ref

定义/转为 响应式

在上面 setup 写的数据都不是响应式的,修改了数据,视图并不会更新

在 Vue3 中提供了两种方式定义响应式数据,先来介绍下 ref

导入 ref 方法

 
  • 你可以先声明一个基本类型变量后再当做 ref 的形参穿进去

  • 或者直接在 ref 中传入

 

 来查看一下 number1 是什么吧

 

 

可以看见的是 number1 是一个 Ref 对象,我们设置的 10 这个值在这个对象的 value 属性上

也就是说我们修改的时候必须要修改的是 number1.value

通过给value属性添加 getter/setter 来实现对数据的劫持

但是在模板上使用的时候 不用写 number1.value 直接写 number1 即可

在模板编译的时候回自动加上 value

 

 

 

使用起来完全没有问题

刚才强调了说 ref 接收 基本类型的数据,那么它可以接收 复杂类型吗,object 类型等,当然可以

给 ref 传入复杂类型,其实它是调用 reactive 来实现的

reactive 下面会提到

ref 获取元素

同样的 ref 还可以用了获取元素

大家在 Vue2.X 中是怎么获取的呢,先在 标签上定义 :ref='XXX' 然后 this.$refs.XXX 来获取

在 Vue3 上获取元素就有些许不同了

1.首先在 模板元素上 ref='XXX' 这里不用 v-bind

 

 

2.在 setup 中

得给 ref 指定类型 HTMLElement

 

如果在组件中需要使用到 haha ,就必须把 haha return 出去合并 data

我们来看看打印的是什么

 

 

可以看见的是 haha 是个 Ref 对象,value 值就是我们想要获取到的元素

然后我们可以对 haha 这个 DOM 元素进行操作,比如这个

 

 

reactive

reactive 接收一个普通对象然后返回该普通对象的响应式代理对象

没错 它的底层就是使用 Proxy 进行代理

简单写个Vue3响应式例子来说下 Proxy

new Proxy(target, handler)

  • target :要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)

  • handler:一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p

 

 

 

reactive 基础用法

导入,当然写的时候,vscode 会自动帮你引入

 

 简单使用

 

 

来看看返回的 Proxy 对象吧

 

 

 

数据都在 target 中,

在模板使用直接 {{obj.name}} 即可

修改直接修改 obj[name] = ‘xxx’

操作代理对象,obj中的数据也会随之变化,同时如果想要在操作数据的时候,界面也要跟着重新更新渲染,那么也是操作代理对象

响应式的数据是深层次的(递归深度响应式)

对于多层嵌套的数据也是响应式的

 

 

shallowReactive

它是一个简单的 reactive ,只把第一层的对象改为响应式,这里就不多说了

使用 ref 传入对象

 

 

 

 

 

实际上是 ref 使用 reactive 来进行操作的

toRefs

这个方法可以把 reactive 响应式对象,转化为 普通对象,普通对象的每个属性都是 Ref 对象,这样的话保证了 reactive 的每个属性还是响应式的,我们还可以把每个属性进行分解使用,这样在组件就不用 obj[属性],代码量减轻了,yyds

 

 

 

可以看见 name 和 age 已经变成了 Ref 对象

我们可以解构 出 name 和 age 单独使用

 

 

toRef

还有一个 toRef 方法,它的作用和 toRefs 差不多,但是它只能把响应式对象/普通对象的某一个属性变为 Ref 对象

可以用来为源响应式对象上的 property 性创建一个 ref。然后可以将 ref 传递出去,从而保持对其源 property 的响应式连接。

 

 

 

拷贝了一份新的数据值单独操作, 更新时相互不影响

当您要将 prop 的 ref 传递给复合函数时,toRef 很有用

可以从官方文档看出,用于在于组件之前的传递数据 从 props 拿出 'foo' 属性给复合函数,复合函数 useSomeFeature,接收的参数 foo 为 Ref 类型,刚好可以使用toRef 来进行转化

判断响应式

几个判断是否哪种响应式创建的方法

1.isRef: 检查一个值是否为一个 ref 对象

 

 2.isReactive: 检查一个对象是否是由 reactive 创建的响应式代理

 

 

 

 3.isReadonly: 检查一个对象是否是由 readonly 创建的只读代理

 

 

 4.isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理

 

 

 

customRef

上面提到了这么多的 Ref 都是 Vue 帮我们内置的,

我们可以通过 customRef 实现我们自己的 Ref

创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并应返回一个带有 get 和 set 的对象。

官方文档给了一个防抖的例子,我们也写个来看

 
   

 

shallowRef 和 shallowReactive

浅的响应式,一般用的不多,我们使用 ref 和 reactive 比较多

shallowReactive

对象结构多层嵌套,但是我们的需求只需要修改最外层的数据,就不用把里面的嵌套结构都转为响应式,这样使用浅的响应式提高性能,只有最外一层是响应式

比较容易理解,我这就里就不举例子了

shallowRef

我们之前说过 ref 也能传入一个对象,实际上还是调用 reactive 返回 Proxy 代理对象,如果内层还有对象,还是使用 reactive 进行处理

 

 同样的 shallowRef 处理 对象类型,是交给 shallowReactive 去完成

 

 

 

这样子我们就明白了,为啥 只处理了 value 的响应式,不进行对象的 reactive 处理,适用于会被替换的数据

【注意】shallowRef 创建一个 ref ,将会追踪它的 value 更改操作,但是并不会对变更后的 value 做响应式代理转换

 

 

 我们来打印下两个对象

 

 

可以看见的是 Ref 的 value 值是用 reactive 返回的 Proxy 对象,

shallowRef 的 value 是普通对象

readonly 和 shallowReadonly

readonly 深度只读

设置普通对象或者是响应式对象为只读,不能进行修改,看上面的名字就知道是深度的,深度是什么概念大家差不多都清楚,递归把内层的每一个属性都设置为只读,进行修改操作就会报错,提高了安全性

基本使用:

用什么就导入什么

 

果然在编译之前就报错了 Error无法分配到 "name" ,因为它是只读属性

无论是内层还是外层都只读,是深度检测的

 

 

shallowReadonly 浅度只读

浅度的话只针对最外面一层不关心 内层

可以看下面的例子 只有外层的 name 报错,修改内层没有错误

 

 

 

toRaw 和 markRaw

这两个用的还是比较少

我这里就简单的过一下

toRaw: 将一个响应式对象转为普通对象

简单使用:

 

 

两个打印出来,一个是响应式对象,通过 toRaw 后变成了普通对象

markRaw: 标记一个对象,让它永远不会转为响应式对象,返回值是本身

比如:一些不变的数据死数据,还有一些第三方类实例,不用转为响应式对象,提高性能

简单使用:

这里使用 两个一样的对象,一个进行 markRaw 处理,一个不进行 markRaw 处理

然后同样使用 reactive 转为 响应式

 

 

 可以看看打印的,被标记过的 obj 并没有转为 Proxy 响应式代理对象

 

 

computed 计算属性

Vue3中使用computed 和Vue2.X 有些不同,这里 computed是一个方法

首先还是得导入 computed 方法

 

参数为一个回调 默认为 get

这里没有实现 set 方法,所以修改下面没有用

参数为一个对象 在这里写 get set

模板和上面一样

 

 

watch 侦听器

和 Vue2.X 的 Watch 使用方法差不多

介绍

watch(data,handler,object)

  1. data:可以是返回值的 getter 函数,也可以是 ref

  2. handler:回调函数

  3. object:可选配置项 { immediate: true }

引入

 

data 为一个 ref

回调函数的参数是 (新值,旧值)

 

可以看见页面第三栏没有显示,因为 name 值没有变化,所以就不用改变,watch的第三个参数是 配置对象,我们在里面可以设置 立即执行 { immediate: true }

就会执行一次 当然这个时候 oldName 为 undefined

 

 

data 为一个 getter

 

 

()=> haha 直接返回一个值,相当于 getter 简写,haha可以不是响应式数据

data 为多个 ref

模板还是之前那个

 

我们可以把多个 ref 放进一个数组里面

newNameAndAgeoldNameAndAge为一个数组保存着 新 和 旧的 [name,age]

data 为 reactive

 

 

这里是对象 会出现问题,立即执行后,

如果加上 立即执行 除了第一次 newInfo为 {name: '小浪',age: 21}

oldInfo 为 undefined ,之后始终返回该对象的当前值

所以 newInfo = oldInfo

对于这个问题,我们得加上配置对象 {deep: true}进行深度检测

深度检测还可以判断多重嵌套

 

watchEffect

这个也是用来监听数据变化,默认就会执行一次所以这里就不需要配置,而且不用指定 data,使用哪些响应式数据就监听哪些

provide / inject

提供 和 注入 是很简单理解的

实现跨层级组件(祖孙)间通信

在多层嵌套组件中使用,不需要将数据一层一层地向下传递

可以实现 跨层级组件 通信

在 父组件中

在 子孙 层级组件使用注入就能够获取到了

Teleport 传送组件

这个组件特别有趣,可以把组件进行传送

to 是目标的地址 body , #XXX , .XXX 这些都是 css 选择器

下面写个例子大家看下就明白了

模板

setup

setup() { 
  // target 
  let target = ref('.li_1')  
  return { 
    target, 
  }
},

利用 按钮 点击来控制 teleport 是否显示, teleport 一渲染,就会跑到 li 下面 

Vue3 生命周期

Vue2.X 对应 Vue3组合API

 

可以看出

beforeCreate 和 created 在Vu3还是能正常使用,在Vue3我们可以用更好更快的 setup 代替

on开头的 生命周期需要 通过 import 导入,在 setup 函数中使用

Vue3 的生命周期 比 Vue2.X 的生命周期快

举个例子:   onBeforeMount 比 beforeMount 快 其他同理

还多个两个钩子:

  • onRenderTriggered 跟踪虚拟 DOM 重新渲染时调用

  • onRenderTracked 当虚拟 DOM 重新渲染被触发时调用

全局API转移

Vue2.X 中 Vue 上面的全局API ,比如自定义指令 Vue.directive,全局组件 Vue.component 在Vue3都进行改变,不再提供 Vue ,而是提供 app

具体改变可以看下面

结语

到了这里我们基本都了解了 Vue3 的一些特性

  • 新的脚手架工具vite

  • 在 Vue3 仍然支持 Vue2 中的大多数特性

  • Vue 组合APi代替了Vue2中的option API ,同一逻辑集中起来,复用性更强了

  • Vue3 使用 TS 编写更好的支持TS

  • Vue3 使用Proxy 代替了Vue2Object.defineProperty() 实现响应式原理

  • 介绍了新的组件: Fragment Teleport Suspense

这里还没有提到的 Vue3 重写了 虚拟DOM ,提高了性能

希望这篇笔记能够帮助到大家,如果我写的不清楚,具体的还得看 官方文档 

参考资料:

Vue3官网文档: https://vue3js.cn/docs/zh

B站资料: https://www.bilibili.com/video/BV1Zy4y1K7SH?p=156

作者:小浪努力学前端

https://juejin.cn/post/7006518993385160711

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值