feat(ref): 实现 ref 值变化检测和依赖触发功能
- 在 shared 包中新增 hasChanged 函数用于比较值是否发生变化 - 修改 RefImpl 类添加 _rawValue 属性存储原始值 - 实现 ref setter 中的值变化检测逻辑 - 添加 triggerRefValue 函数用于触发 ref 依赖更新 - 优化 ref 的 getter 和 setter 方法实现响应式更新
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { createDep, Dep } from './dep'
|
import { createDep, Dep } from './dep'
|
||||||
import { toReactive } from './reactive'
|
import { toReactive } from './reactive'
|
||||||
import { activeEffect, track, trackEffects } from './effect'
|
import { activeEffect, triggerEffects, trackEffects } from './effect'
|
||||||
|
import { hasChanged } from '@vue/shared'
|
||||||
|
|
||||||
export interface Ref<T = any> {
|
export interface Ref<T = any> {
|
||||||
value: T
|
value: T
|
||||||
@@ -17,20 +18,36 @@ function createRef(rawValue: unknown, shallow: boolean) {
|
|||||||
}
|
}
|
||||||
class RefImpl<T> {
|
class RefImpl<T> {
|
||||||
private _value: T
|
private _value: T
|
||||||
|
private _rawValue: T
|
||||||
public dep?: Dep = undefined
|
public dep?: Dep = undefined
|
||||||
public readonly __v_isRef = true
|
public readonly __v_isRef = true
|
||||||
constructor(
|
constructor(
|
||||||
value: T,
|
value: T,
|
||||||
public readonly __v_isShallow: boolean
|
public readonly __v_isShallow: boolean
|
||||||
) {
|
) {
|
||||||
|
this._rawValue = value
|
||||||
this._value = __v_isShallow ? value : toReactive(value)
|
this._value = __v_isShallow ? value : toReactive(value)
|
||||||
}
|
}
|
||||||
get value() {
|
get value() {
|
||||||
trackRefValue(this)
|
trackRefValue(this)
|
||||||
return this._value
|
return this._value
|
||||||
}
|
}
|
||||||
set value(newValue) {}
|
set value(newValue) {
|
||||||
|
if (hasChanged(newValue, this._rawValue)) {
|
||||||
|
this._rawValue = newValue
|
||||||
|
this._value = toReactive(newValue)
|
||||||
|
triggerRefValue(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//触发依赖
|
||||||
|
export function triggerRefValue(ref) {
|
||||||
|
if (ref.dep) {
|
||||||
|
triggerEffects(ref.dep)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//收集依赖
|
||||||
export function trackRefValue(ref) {
|
export function trackRefValue(ref) {
|
||||||
if (activeEffect) {
|
if (activeEffect) {
|
||||||
trackEffects(ref.dep || (ref.dep = createDep()))
|
trackEffects(ref.dep || (ref.dep = createDep()))
|
||||||
|
|||||||
@@ -3,3 +3,11 @@ export const isArray = Array.isArray
|
|||||||
|
|
||||||
export const isObject = (val: unknown) =>
|
export const isObject = (val: unknown) =>
|
||||||
val !== null && typeof val === 'object'
|
val !== null && typeof val === 'object'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对比两个数据是否发生改变
|
||||||
|
* @param value
|
||||||
|
* @param oldValue
|
||||||
|
*/
|
||||||
|
export const hasChanged = (value: any, oldValue: any): boolean =>
|
||||||
|
!Object.is(value, oldValue)
|
||||||
|
|||||||
Reference in New Issue
Block a user