mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7mobile wallpaper 8mobile wallpaper 9mobile wallpaper 10mobile wallpaper 11mobile wallpaper 12mobile wallpaper 13mobile wallpaper 14mobile wallpaper 15mobile wallpaper 16mobile wallpaper 17
3606 字
10 分钟
Vue3
2026-04-05
2026-04-12

创建Vue3#

注意开发者工具要更新才能点亮

使用vite:

一些变化#

main.js的变化#

不再使用引入并创建整个vm的方式,而是引入一个vue的方法

createApp创建一个应用实例,然后渲染这个实例

对应mount方法的还有一个相反的unmount方法

不兼容vue2的写法,也无法直接引入vue了

template可以没有根标签#

开发者工具应安装vue3#

vue2与vue3的响应式区别#

vue2增删属性必须使用$set和$delete这两个api才能被响应

vue3通过reactive生成的对象直接增删属性是可以被响应的

删除使用delete关键字释放资源

常用Composition(组合式)API#

setup#

setup是值为函数的新配置项,半取代了data与methods

(data内也可配置函数,但不具备响应式,必须配置在methods)

属性名冲突时,setup的优先级高于data/methods,并且仅支持data/methods向setup单向访问,不应混用

由于setup是函数,而配置data/methods时是使用对象,因此setup使用的不是key-val的形式,而是直接在函数里面写数据

由于数据与函数都在同一作用域,引用数据无需使用this.name

同步组件内,setup不允许被async(异步函数)修饰,因为返回值会被自动包装为promise。访问时得用.then,因而不是一个单独的对象

setup返回对象时,则类似data,属性方法都可以直接使用,但方法无法引起数据的响应式变化,除非数据使用ref函数

setup返回渲染函数时,会将整个页面替换掉,以渲染函数为主

要构造渲染函数,还需要引入h,设置返回值为h函数的返回值

ref函数#

ref函数在使用时需要引入

原本在setup内的数据无法实现响应式,但调用ref函数可实现

在setup内通过ref函数配置数据:

本质上,调用ref后返回的数据变成了RefImpl(引用实现)对象

setup里的函数要实现响应式操作,得修改对象里的value属性值,从而触发getter和setter

vue在解析模板时会自动识别并读取value值,无需手动读取

ref处理对象类型#

ref将对象类型的数据处理成Proxy类型,作为RefLmpl的value

读取xx.valuie时,会返回该对象的Proxy形式,而不再包含value

因此读取对象内属性值的操作应为xx.value.xx

即便没有第二层,多层的数据也能被监测到并进行响应式变化,因为RefImpl只有处理基本数据类型才用getter/setter

reactive函数#

使用reactive函数仍然需要引入

reactive的使用方式与ref相同,都是直接传入需要响应的值

reactive将收到的值转为Proxy对象,使用时无需找value属性

reactive也可以用于处理数组的响应式,并且可以深度响应

**为避免因使用ref而重复使用value,应该尽量将数据设置成对象,**并使用reactive生成Proxy对象数据,作为一个setup返回值内的一个属性

Vue3的响应式原理#

vue2的响应式只能捕获增删的时候

vue3实现响应式使用了window自带的Proxy方法

对代理对象的任何修改都会被proxy捕获到,完成对源数据的修改,从而再反馈给代理对象

使用Proxy的getter和setter,外加一个deleteProperty

getter的两个参数,第一个target是源对象,第二个propName是读取的属性名,读取时要避免引起递归

setter的三个参数,第一个target是源对象,第二个propName是修改的属性名,第三个是原属性值

deleteProperty的两个参数,第一个target是源对象,第二个propName是删除的属性名

vue底层不再使用Object.defineProperty,改为使用Reflect.defineProperty,因为Object的重复定义会引发错误并终端线程,而reflect仅返回是否正常运行结果,不影响后续代码执行

reactive对比ref#

在使用时,可以在setup内通过reactive定义一个data对象,然后将这个对象作为返回值,达成类似vue2的数据书写方式

setup的两个注意点#

computed函数#

setup内不再作为配置项去配置,而是一个函数,用法基本一致

仍需先引入

使用的时候传入参数有两个形式

传入回调函数的时候是简写形式,没有多余配置项,回调函数直接返回计算好的数值。并且此时的计算属性是只读的

可以直接在reactive代理对象上配置一个计算属性

传入对象的时候,包含getter和setter,可以读写

watch函数#

vue2配置方式仍然可用,depp也是可选项

vue3的watch是函数,第一个参数是要监视的数据,第二个参数是回调函数或者对象,第三个参数是配置项

情况一:

包含两个参数newval和oldval,

用于监视ref定义的一个响应式数据

情况二:

可以监视ref所定义的多个响应式数据

watch的第一个参数变为数组

回调函数的两个参数变为多个newval和oldval组合的数组

情况三:

监视reactive所定义的对象数据时,

无法正确获得oldVal,并且强制开启了深度监视

如图的deep其实是无效配置

情况四:

监视reactive所定义的对象数据的某个属性

此时watch函数第一个参数变为回调函数,返回值为数据

情况五:

监视reactive所定义的对象数据的某些属性

watch函数的参数变为回调函数数组

回调函数的参数变为newval和oldval的数组

情况六:

监视reactive所定义的对象数据的某些对象属性

虽然监视reactive对象的属性在参数形式时强制开启深度监视,但是在监视reactive对象的对象属性时需要手动配置deep才能深度监视

watch时value的问题#

监视ref时无需.value,因为.value之后会把数据取出来,变成监视一个固定值,因此直接监视整个ref实例对象即可,newval与oldval都是value值

如果监视的数据是对象,并且通过ref生成,则需要.value,此时传的是reactive定义的对象,并且会强制对其深度监视。或者不.value,但是自己手动配置deep

watchEffect函数#

watchEffect函数只有一个参数,参数为回调函数

这个回调函数内用到了哪个数据,则对哪个数据进行监视

Vue3生命周期#

Vue3去掉了判断是否有el的选项,而是在一开始就必须要有el

另外,beforeUnmount跟unmounted更名为beforeDestroy跟destryed,将销毁换成了卸载组件

vue3使用组合式api,使得生命周期钩子可以在setup里使用

使用组合式api的钩子时也需要引入

如果仍以vue2的形式配置钩子,则setup的执行时机在beforeCreate之前

如果在vue3中使用组合式api,则setup就相当于beforeCreate与created两个钩子

这些组合式api的钩子均为函数形式参数为回调函数

如果vue3组合式api与vue2的钩子同时使用,则vue3的优先

自定义hook函数#

实现捕获鼠标点击坐标#

使用原来的方法,需要在组件内window上挂载监听并及时卸载

而且要把逻辑函数写在外部,挂载和卸载的时候都需要函数名

使用hook,将该部分代码移植到公共区

在src目录下创建hooks文件夹将该部分代码封装到该文件夹下usePoints.js文件内

**将该实现的全部逻辑封装成函数,且返回数据,**将该函数暴露出去

注意所使用的vue方法都需要重新引入

vue在setup里写的的组合式api都与hook封装的函数类似

使用该函数时需要引入并调用

vue2中的mixin#

toRef与toRefs#

使用时需要引入

对name1的赋值不会引发任何响应式变化,实际上就是普通赋值

而name2使用toRef方法,将name2绑定到了person的name属性,对name2的读写会引发person的name属性的响应式变化

如果使用ref而不是toRef,则name2与person不绑定,是新对象

name2通过toRef函数成为了一个RefImpl对象,并引用了原数据

通过该方法,可以将打包的数据逐个解包,且保留响应式变化

**作为setup的返回值,**在返回时拆解person

使用toRefs批量处理#

toRefs的批量处理会把所以对象的属性都转化成RefImpl,对于包含子对象的对象,也会正常将其变成Proxy对象

使用…直接简写拆分所有属性

其他Compisition API#

注意:所有组合式api使用时都要引入

shallowReactive与shallowRef:数据的浅层响应式#

shallowReactive与reactive的区别在于是否深层响应式

shallowRef与ref的区别在于,使用对象时是否有响应式,因为不求助reactive,value值就是普通对象类型

readonly与shallowReadonly:响应式数据转为(深/浅)只读#

readonly默认是深只读,shallowReadonly只让第一层属性只读

ref数据没有深层,一般用浅只读

reactive数据有深层,一般用深只读

toRaw与markRaw:把响应式对象转为原始普通对象#

toRaw只能将reactive生成的响应式对象退回

markRaw:阻止对象变成响应式对象

应用:

reactive定义的对象是深层响应式的,并且在该对象上追加属性的时候,会自动转为响应式属性。如果追加的数据不希望其被转为响应式,则应使用markRaw(如第三方库、不可变数据)


customRef:自定义ref#

如:实现延迟响应式(防抖)

customRef是一个函数,参数为回调函数,该回调必须返回对象

回调的参数有两个,track与trigger

get里使用track()追踪响应式数据,

set里使用tigger()触发响应式数据的改变

返回的对象必须包含两个函数:get()和set()

get没有参数,由于作用域问题可以直接取得响应式的value,同时需要使用track()实现对响应式数据的追踪

set的参数为修改时,想要修改的新值。在set里可以把响应式的value直接进行修改,不会引发递归,但是此时getter未响应**,需要使用trigger触发一次重新解析**

如果需要延迟响应,只需要修改触发响应的逻辑

如果只设置定时器,而不在设置定时器之前清除旧的定时器,则会使得新旧定时器堆积在一起触发

provide与inject:祖孙(跨级)通信#

provide是一个函数,参数为属性和值(祖先组件)

inject是一个函数,参数为需要使用的属性(后代组件)

只要祖先组件进行provide,任何后代组件都可以进行inject

一般只有祖孙及其后代进行注入,父子不使用注入但其实能使用

响应式数据的判断#

返回值均为布尔值

注意:readonly只改变是否只读,原数据是什么类型还是什么类型

CompositionAPI的优势#

optionsAPI的缺陷:

compositionAPI的优势:使用hook函数将代码聚合,降低耦合度

新的组件#

Fragment:代替组件根标签#

Teleport:组件html移动#

teleport标签的作用是,将指定的html结构传送到指定的html标签内

如在设置弹窗时,弹窗显示时可能会将父组件撑开,而如果要将弹窗进行定位,可能需要层层去找父组件才能进行定位

使用teleport标签可将弹窗移动到指定标签内,此处放在body内

Suspense(目前处在试验阶段)#

异步组件#

如果都是用同步组件,则嵌套的组件的加载速度是以速度最慢的为准,容易造成一起堵塞

正常的引入组件,是同步组件

引入异步组件,需要先从vue引入定义异步的函数,再引入组件

该函数的参数是一个回调,回调的返回值是import函数,参数是引入的组件的位置

Suspense实现未加载时的显示#

将组件套在Suspense标签内,内部包含多个template标签

在template标签上添加v-slot属性(注意使用的是冒号),

默认的slot包含加载的原标签,当该标签未被加载出来时,使用slot为fallback的标签代替原本的标签

异步组件内setup可返回promise#

如果引入异步组件,可以通过返回一个promise的方式,主动实现组件的延迟加载(本质上是延迟了setup的返回,延长钩子周期)

Vue3中其他改变#

全局API的转移#

其他改变#

native用于声明原生事件,改为在子组件声明自定义事件

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Vue3
https://krisreynard.top/posts/vue3/
作者
Kris_Reynard
发布于
2026-04-05
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录