文章目录
- 一、前言
- 二、`readonly`
- 三、`shallowRef`
- 四、`shallowReactive`
- 五、`toRef` & `toRefs`
- 5.1、 `toRef`
- 5.2、`toRefs`
- 六、`toRaw & markRaw & unref`
- 6.1、`toRaw`
- 6.2、`markRaw`
- 6.3、`unref`
- 七、`effectScope & onScopeDispose`
- 7.1、收集副作用
- 7.2、全局状态管理
- 八、`provide & inject`
- 九、最后
一、前言
今天给大家分享几个很少人用,但是又非常有用的 Vue3
的 API
,废话不多说,往下看吧~
文章提示:下文的
无效
不触发视图
不触发响应式更新
不被追踪
这些词汇,想表达的意思是一样的,意思都是不被追踪
二、readonly
顾名思义,就是只读的意思,如果你的数据被这个 API
包裹住的话,那么修改之后并不会触发响应式,并且会提示警告
readonly
的用途一般用于一些 hooks
暴露出来的变量,不想外界去修改,比如我封装一个 hooks
,这样去做的话,那么外界只能用变量,但是不能修改变量,这样大大保护了 hooks
内部的逻辑~
三、shallowRef
shallowRef
用来包住一个基础类型或者引用类型,如果是基础类型那么跟 ref
基本没区别,如果是引用类型的话,那么直接改深层属性是不能触发响应式的,除非直接修改引用地址,如下:
注意:改深层属性能改数据,只是没触发响应式,所以当下一次响应式触发的时候,你修改的深层数据会渲染到页面上~
shallowRef
的用处主要用于一些比较大的但又变化不大的数据,比如我有一个表格数据,通过接口直接获取,并且主要用在前端展示,需要修改一些深层的属性,但是这些属性并不需要立即表现在页面上,比如以下例子,我只需要展示 name
、age
字段,至于 isOld
字段并不需要展示,我想要计算 isOld
但是又不想触发响应式更新,所以可以用 shallowRef
包起来,进而减少响应式更新,优化性能
四、shallowReactive
shallowReactive
用来包住一个引用类型,被包住后,修改第一层才会触发响应式更新,也就是浅层的属性,修改深层的属性并不会触发响应式更新
注意:改深层属性能改数据,只是没触发响应式,所以当下一次响应式触发的时候,你修改的深层数据会渲染到页面上~
shallowReactive
用的比较少,shallowReactive
的用处跟 shallowRef
比较像,都是为了让一些比较大的数据能减少响应式更新,进而优化性能
五、toRef
& toRefs
5.1、 toRef
先说说 toRef
吧,我们平时在使用 reactive
的时候会有一个苦恼,那就是解构,比如看以下例子,我们为了少些一些代码,解构出来了 name
并放到模板里渲染,但是当我们想改原数据的时候,发现 name
并不会更新,这就是解构出来基础类型的苦恼
这时我们可以使用 toRef
,这个时候我们直接修改 name
也会触发原数据的修改,修改原数据也会触发 name
的修改
5.2、toRefs
但是如果是属性太多了,我们想一个一个去用 toRef
的话会写很多代码
所以我们可以使用 toRefs
一次性解构
六、toRaw & markRaw & unref
6.1、toRaw
toRaw
可以把一个响应式 reactive
转成普通对象,也就是把响应式对象转成非响应式对象
toRaw
主要用在回调传参中,比如我封装一个 hooks
,我想要把 hooks
内维护的响应式变量转成普通数据,当做参数传给回调函数,可以用 toRaw
6.2、markRaw
markRaw
可以用来标记响应式对象里的某个属性不被追踪,如果你的响应式对象里有某个属性数据量比较大,但又不想被追踪,你可以使用 markRaw
6.3、unref
unref
相当于返回 ref
的 value
七、effectScope & onScopeDispose
effectScope
可以有两个作用:
- 收集副作用
- 全局状态管理
7.1、收集副作用
比如我们封装一个共用的 hooks
,为了减少页面隐患,肯定会统一收集副作用,并且在组件销毁的时候去统一消除,比如以下代码:
但是这么收集很麻烦, effectScope
能帮我们做到统一收集,并且通过 stop
方法来进行清除,且 stop
执行的时候会触发 effectScope
内部的 onScopeDispose
我们可以利用 effectScope
& onScopeDispose
来做一些性能优化,比如下面这个例子,我们封装一个鼠标监听的 hooks
但是如果在页面里调用多次的话,那么势必会往 window
身上监听很多多余的事件,造成性能负担,所以解决方案就是,无论页面里调用再多次 useMouse
,我们只往 window
身上加一个鼠标监听事件
7.2、全局状态管理
现在 Vue3
最火的全局状态管理工具肯定是 Pinia
了,那么你们知道 Pinia
的原理是什么吗?原理就是依赖了 effectScope
所以我们完全可以自己使用 effectScope
来实现自己的局部状态管理,比如我们封装一个通用组件,这个组件层级比较多,并且需要共享一些数据,那么这个时候肯定不会用 Pinia
这种全局状态管理,而是会自己写一个局部的状态管理,这个时候 effectScope
就可以排上用场了
vueuse
中的 createGlobalState
就是为了这个而生
八、provide & inject
Vue3
用来提供注入的 API
,主要是用在组件的封装,比如那种层级较多的组件,且子组件需要依赖父组件甚至爷爷组件的数据,那么可以使用 provide & inject
,最典型的例子就是 Form
表单组件,可以去看看各个组件库的源码,表单组件大部分都是用 provide & inject
来实现的,比如 Form
、Form-Item
、Input
这三个需要互相依赖对方的规则、字段名、字段值,所以用 provide & inject
会更好。具体用法看文档吧~https://cn.vuejs.org/guide/components/provide-inject.html
九、最后
本人每篇文章都是一字一句码出来,希望对大家有所帮助,多提提意见。顺手来个三连击,点赞👍收藏💖关注✨,一起加油☕