vue组合式API相关知识
setup
setup
函数是一个新的组件选项。作为在组件内使用 Composition API 的入口点
- 它在创建组件实例,初始化props后调用,从生命周期的角度看,他会在
beforeCreate
钩子之前被调用 setup
会返回一个对象,该对象属性会被合并到组件模板渲染的上下文中。(ref定义的数据会自动解开,无需.value引用)setup(props, context){}
,接收props作为一个参数,且是响应式的,如果对其解构则会失去响应。第二个参数是上下文对象,类似vue2中的this,可以对其进行解构获取内部的一些属性。- this在setup中不可用
响应式系统API
reactive
接收一个普通对象然后返回该普通对象的响应式代理。返回的对象不等于原始的对象。
1 |
|
等同于 2.x 的 Vue.observable()
ref
接受一个参数值并返回一个响应式且可改变的 ref 对象。ref 对象拥有一个指向内部值的单一属性 .value
如果传入的是一个对象,则会调用reactive进行处理。
- 当ref作为渲染上下文的属性(通过setup函数返回),在模板中使用会自动解套,不需要写
.value
- 当ref作为reactive对象中的属性被访问的时候也会自动解套,从
Array
或者Map
等原生集合类中访问 ref 时,则不会。 - 可以通过传递范型参数来覆盖默认的推导
1 |
|
computed
计算属性可有两种方式
传入一个getter函数,返回一个不可修改的ref对象
1
2const count = ref<number>(0)
const comp = computed(() => count.value + 1)传入一个拥有get和set函数的对象,可手动修改
1
2
3
4
5
6
7const count = ref<number>(0)
const comp = computed({
get: () => count.value + 1,
set: val => {
count.value = val - 1
}
})
readonly
传入一个对象(响应式、普通)或ref,返回一个只读的代理,只读代理是深层的,对象内部的任何嵌套属性都是只读的。
watchEffect
立即执行传入的一个函数,并响应式追踪其依赖,并在其依赖变更时重新运行该函数。
停止监听:
当 watchEffect
在组件的 setup()
函数或生命周期钩子被调用时, 侦听器会被链接到该组件的生命周期,并在组件卸载时自动停止。
也可以调用其返回值来停止监听:
1 |
|
清理失效时的回调:
副作用传入的函数可以接收一个 onInvalidate
函数作入参, 用来注册清理失效时的回调
失效回调会被触发的条件:
- 副作用即将重新执行时
- 侦听器被停止
副作用刷新时机:
当一个用户定义的副作用函数进入队列时, 会在所有的组件更新后执行:
可以传递一个拥有 flush
属性的对象作为选项,默认是‘post’,在组件更新后执行副作用,值也可以是同步‘sync’、之前‘pre’
1 |
|
watch
它类似于vue2.x的this.$watch,需要侦听特定的数据源,并在回调函数中执行副作用。默认情况是懒执行的,也就是说仅在侦听的源变更时才执行回调。
与watchEffect对比,watch特点:
- 懒执行副作用
- 更明确哪些状态的改变会触发侦听器重新运行副作用
- 访问侦听状态变化前后的值
监听单个数据源
监听器的数据源可以是一个getter函数也可以是ref
1 |
|
监听多个数据源
可以使用数组来同时侦听多个源
1 |
|
生命周期钩子函数
只能在setup() 期间同步使用
与 2.x 版本生命周期相对应的组合式 API
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- update -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroy -> onUnmounted
新增的钩子函数 (用于调试)
onRenderTracked
onRenderTriggered
依赖注入
provide/inject提供依赖注入,只能在setup中调用
1 |
|
inject
接受一个可选的的默认值作为第二个参数。如果未提供默认值,并且在 provide 上下文中未找到该属性,则 inject
返回 undefined
。
模板Refs
可以获得对模板内元素或组件实例的引用,我们可以像往常一样在 setup()
中声明一个 ref 并返回
将root暴露在渲染上下文,通过ref=”root”,绑定到dom节点上作为其ref
在 Virtual DOM patch 算法中,如果一个 VNode 的 ref
对应一个渲染上下文中的 ref,则该 VNode 对应的元素或组件实例将被分配给该 ref。 这是在 Virtual DOM 的 mount / patch 过程中执行的,因此模板 ref 仅在渲染初始化后才能访问。
- 配合 render 函数 / JSX 的用法
1 |
|
在
v-for
中使用使用函数型的 ref(3.0 提供的新功能)来自定义处理方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<template>
<div v-for="(item, i) in list" :ref="el => { divs[i] = el }">
{{ item }}
</div>
</template>
<script>
import { ref, reactive, onBeforeUpdate } from 'vue'
export default {
setup() {
const list = reactive([1, 2, 3])
const divs = ref([])
// 确保在每次变更之前重置引用
onBeforeUpdate(() => {
divs.value = []
})
return {
list,
divs,
}
},
}
</script>
响应式系统工具集
unref
如果参数是一个 ref 则返回它的 value
,否则返回参数本身。
1 |
|
toRef
toRef
可以用来为一个 reactive 对象的属性创建一个 ref。这个 ref 可以被传递并且能够保持响应性。
1 |
|
当要将一个 prop 中的属性作为 ref 传给组合逻辑函数时,toRef
就派上了用场:
1 |
|
toRefs
把一个响应式对象转换成普通对象,该普通对象的每个 property 都是一个 ref ,和响应式对象 property 一一对应。
当想要从一个组合逻辑函数中返回响应式对象时,用 toRefs
是很有效的,该 API 让消费组件可以 解构 / 扩展(使用 ...
操作符)返回的对象,并不会丢失响应性:
1 |
|
isRef
检查一个值是否为一个 ref 对象
isProxy
检查一个对象是否是由 reactive
或者 readonly
方法创建的代理
isReactive
检查一个对象是否是由 reactive
创建的响应式代理。
isReadonly
检查一个对象是否是由 readonly
创建的只读代理。
高级响应式系统 API
customRef
customRef
用于自定义一个 ref
,可以显式地控制依赖追踪和触发响应,接受一个工厂函数,两个参数分别是用于追踪的 track
与用于触发响应的 trigger
,并返回一个一个带有 get
和 set
属性的对象
使用customRef实现带防抖功能的v-model
1
<input v-model="text" />
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26function useDebouncedRef(value, delay = 200) {
let timer
return customRef((track, trigger) => {
return {
get() {
track()
return value
},
set(newVal) {
clearTimeout(timer)
timer = setTimeout(() => {
value = newVal
trigger()
}, delay)
}
}
})
}
export default {
setup() {
return {
text: useDebouncedRef('hello'),
}
},
}
markRaw
显式标记一个对象为“永远不会转为响应式代理”,函数返回这个对象本身。
1 |
|
shallowReactive
只为某个对象的私有(第一层)属性创建浅层的响应式代理,不会对“属性的属性”做深层次、递归地响应式代理,而只是保留原样。
shallowReadonly
只为某个对象的自有(第一层)属性创建浅层的只读响应式代理,同样也不会做深层次、递归地代理,深层次的属性并不是只读的。
shallowRef
创建一个 ref ,将会追踪它的 .value
更改操作,但是并不会对变更后的 .value
做响应式代理转换(即变更不会调用 reactive
)
1 |
|
toRaw
返回由 reactive
或 readonly
方法转换成响应式代理的普通对象。这是一个还原方法,可用于临时读取,访问不会被代理/跟踪,写入时也不会触发更改。不建议一直持有原始对象的引用。请谨慎使用。
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!