Vue3响应式API是Vue3中新增的一种API,它可以帮助开发者更好地管理数据流,并且可以更快地实现数据的双向绑定。
Vue3响应式API的核心是响应式对象(Reactive Object),它是一个特殊的JavaScript对象,其中包含了一些特殊的属性。这些特殊的属性会被Vue3监听,当这些属性发生变化时,Vue3会自动重新渲染页面。
使用Vue3响应式API时,我们需要使用ref函数来创建一个Reactive Object。ref函数有两个参数:value 和 shallow。value表示要创建Reactive Object的原始数据,shallow表示是否将原始数据作为Reactive Object的直接子元素。如果shallow被设置为true,则原始数据将作为Reactive Object的直接子元素而不会再进行递归处理。
const reactiveObject = ref({ name: 'John', age: 20 });
上面代码中我们使用ref函数创建了一个Reactive Object,该对象包含name 和 age 两个字段。当我们修改reactiveObject中name字段时(例如将name字段修改成'Tom' ), Vue3就会自动重新render页面来显示最新的name字段内容。
本节例子中代码使用的单文件组件语法
computed
使用 getter 函数,并为从 getter 返回的值返回一个不变的响应式 ref 对象。
const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // error
或者,它可以使用具有 get
和 set
函数的对象来创建可写的 ref 对象。
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => {
count.value = val - 1
}
})
plusOne.value = 1
console.log(count.value) // 0
类型声明:
// read-only
function computed<T>(getter: () => T): Readonly<Ref<Readonly<T>>>
// writable
function computed<T>(options: { get: () => T; set: (value: T) => void }): Ref<T>
watchEffect
在响应式地跟踪其依赖项时立即运行一个函数,并在更改依赖项时重新运行它。
const count = ref(0)
watchEffect(() => console.log(count.value))
// -> logs 0
setTimeout(() => {
count.value++
// -> logs 1
}, 100)
类型声明:
function watchEffect(
effect: (onInvalidate: InvalidateCbRegistrator) => void,
options?: WatchEffectOptions
): StopHandle
interface WatchEffectOptions {
flush?: "pre" | "post" | "sync" // default: "pre"
onTrack?: (event: DebuggerEvent) => void
onTrigger?: (event: DebuggerEvent) => void
}
interface DebuggerEvent {
effect: ReactiveEffect
target: any
type: OperationTypes
key: string | symbol | undefined
}
type InvalidateCbRegistrator = (invalidate: () => void) => void
type StopHandle = () => void
参考:watchEffect
指南
watch
watch
API 与选项式 API this.$watch (以及相应的 watch 选项) 完全等效。watch
需要侦听特定的 data 源,并在单独的回调函数中副作用。默认情况下,它也是惰性的——即,回调是仅在侦听源发生更改时调用。
watch
允许我们:
侦听器 data 源可以是返回值的 getter 函数,也可以是 ref:
// 侦听一个getter
const state = reactive({ count: 0 })
watch(
() => state.count,
(count, prevCount) => {
}
)
// 直接侦听一个ref
const count = ref(0)
watch(count, (count, prevCount) => {
})
侦听器还可以使用数组同时侦听多个源:
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
})
watchEffect
共享行为
watch
与 watchEffect
在手动停止,副作用无效 (将 onInvalidate
作为第三个参数传递给回调),flush timing 和 debugging 有共享行为。
类型声明:
// 侦听单一源
function watch<T>(
source: WatcherSource<T>,
callback: (
value: T,
oldValue: T,
onInvalidate: InvalidateCbRegistrator
) => void,
options?: WatchOptions
): StopHandle
// 侦听多个源
function watch<T extends WatcherSource<unknown>[]>(
sources: T
callback: (
values: MapSources<T>,
oldValues: MapSources<T>,
onInvalidate: InvalidateCbRegistrator
) => void,
options? : WatchOptions
): StopHandle
type WatcherSource<T> = Ref<T> | (() => T)
type MapSources<T> = {
[K in keyof T]: T[K] extends WatcherSource<infer V> ? V : never
}
// 参见 `watchEffect` 类型声明共享选项
interface WatchOptions extends WatchEffectOptions {
immediate?: boolean // default: false
deep?: boolean
}
参考:watch
指南
#Data Property组件的 data 选项是一个函数。Vue 在创建新组件实例的过程中调用此函数。它应该返回一个对象,然后 Vue 会通过响...
#用 v-for 把一个数组对应为一组元素我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式...
该页面假设你已经阅读过了组件基础。如果你还对组件不太了解,推荐你先阅读它。#组件名在注册一个组件的时候,我们始终需要给它...
该页面假设你已经阅读过了组件基础。如果你还对组件不太了解,推荐你先阅读它。#事件名不同于组件和 prop,事件名不存在任何自动...