【vue3源碼】十柒昏、響應(yīng)式API中的工具函數(shù)

【vue3源碼】十显蝌、響應(yīng)式API中的工具函數(shù)

參考代碼版本:vue 3.2.37

官方文檔:https://vuejs.org/

isRef

export function isRef(r: any): r is Ref {
  return !!(r && r.__v_isRef === true)
}

通過對象中是否存在__v_isRef屬性并且__v_isRef對應(yīng)值為true來判斷是否為ref咳燕。

unref

export function unref<T>(ref: T | Ref<T>): T {
  return isRef(ref) ? (ref.value as any) : ref
}

如果是ref則返回ref.value勿决,否則直接返回ref

toRef

export function toRef<T extends object, K extends keyof T>(
  object: T,
  key: K,
  defaultValue?: T[K]
): ToRef<T[K]> {
  const val = object[key]
  return isRef(val)
    ? val
    : (new ObjectRefImpl(object, key, defaultValue) as any)
}

toRef接收三個參數(shù):object待轉(zhuǎn)換的對象、key待轉(zhuǎn)換的key招盲、defaultValue默認(rèn)值低缩。

如果object[key]ref,則直接返回object[key]曹货。否則返回一個ObjectRefImpl實例咆繁。

class ObjectRefImpl<T extends object, K extends keyof T> {
  public readonly __v_isRef = true

  constructor(
    private readonly _object: T,
    private readonly _key: K,
    private readonly _defaultValue?: T[K]
  ) {}

  get value() {
    const val = this._object[this._key]
    return val === undefined ? (this._defaultValue as T[K]) : val
  }

  set value(newVal) {
    this._object[this._key] = newVal
  }
}

ObjectRefImpl構(gòu)造器中會分別將objectkey顶籽、defaultValue保存至自己的私有屬性中玩般,當(dāng)獲取ObjectRefImpl實例的value屬性時,會從this._object中獲取數(shù)據(jù)礼饱,由于this._object和原來的object內(nèi)存地址是一致的坏为,所以這和直接使用object獲取key獲取數(shù)據(jù)沒有區(qū)別,只不過經(jīng)過toRef轉(zhuǎn)換之后镊绪,可以和ref那樣匀伏,通過value屬性進行取值、設(shè)值蝴韭。

toRefs

export function toRefs<T extends object>(object: T): ToRefs<T> {
  if (__DEV__ && !isProxy(object)) {
    console.warn(`toRefs() expects a reactive object but received a plain one.`)
  }
  const ret: any = isArray(object) ? new Array(object.length) : {}
  for (const key in object) {
    ret[key] = toRef(object, key)
  }
  return ret
}

toRefs中會聲明一個新的對象或數(shù)組够颠,然后遍歷objectkey值,并調(diào)用toRef榄鉴,將結(jié)果存入新的對象或數(shù)組中履磨,最后返回這個新的對象或數(shù)組。

isReactive

export function isReactive(value: unknown): boolean {
  if (isReadonly(value)) {
    return isReactive((value as Target)[ReactiveFlags.RAW])
  }
  return !!(value && (value as Target)[ReactiveFlags.IS_REACTIVE])
}

如果value是只讀的庆尘,那么就對valueReactiveFlags.RAW屬性繼續(xù)調(diào)用isReactive剃诅;否則根據(jù)valueReactiveFlags.IS_REACTIVE屬性判斷是否為reactive

isReadonly

export function isReadonly(value: unknown): boolean {
  return !!(value && (value as Target)[ReactiveFlags.IS_READONLY])
}

通過valueReactiveFlags.IS_READONLY屬性判斷是否只讀驶忌。

isProxy

isProxy是用來判斷value是否為reactivereadonly矛辕,并不是用來判斷valueproxy類型的

export function isProxy(value: unknown): boolean {
  return isReactive(value) || isReadonly(value)
}

toRaw

獲取傳入對象的原始對象。

export function toRaw<T>(observed: T): T {
  const raw = observed && (observed as Target)[ReactiveFlags.RAW]
  return raw ? toRaw(raw) : observed
}

observedReactiveFlags.RAW屬性可以返回對象的原始對象位岔,但這個原始對象有可能也是可以響應(yīng)式對象(如readonly(reactive(obj)))如筛,所以遞歸調(diào)用toRaw堡牡,以獲取真正的原始對象抒抬。

markRaw

將對象標(biāo)記為永遠(yuǎn)不能轉(zhuǎn)為reactive對象。

export function markRaw<T extends object>(
  value: T
): T & { [RawSymbol]?: true } {
  def(value, ReactiveFlags.SKIP, true)
  return value
}

通過Object.definePropertyvalueReactiveFlags.SKIP(不會被遍歷)屬性標(biāo)記為true晤柄。當(dāng)嘗試創(chuàng)建reactive時擦剑,會檢查該值。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市惠勒,隨后出現(xiàn)的幾起案子赚抡,更是在濱河造成了極大的恐慌,老刑警劉巖纠屋,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涂臣,死亡現(xiàn)場離奇詭異,居然都是意外死亡售担,警方通過查閱死者的電腦和手機赁遗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來族铆,“玉大人岩四,你說我怎么就攤上這事「缛粒” “怎么了剖煌?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逝淹。 經(jīng)常有香客問我耕姊,道長,這世上最難降的妖魔是什么创橄? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任箩做,我火速辦了婚禮,結(jié)果婚禮上妥畏,老公的妹妹穿的比我還像新娘邦邦。我一直安慰自己,他們只是感情好醉蚁,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布燃辖。 她就那樣靜靜地躺著,像睡著了一般网棍。 火紅的嫁衣襯著肌膚如雪黔龟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天滥玷,我揣著相機與錄音氏身,去河邊找鬼。 笑死惑畴,一個胖子當(dāng)著我的面吹牛蛋欣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播如贷,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼陷虎,長吁一口氣:“原來是場噩夢啊……” “哼到踏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起尚猿,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤窝稿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后凿掂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伴榔,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年庄萎,在試婚紗的時候發(fā)現(xiàn)自己被綠了潮梯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡惨恭,死狀恐怖秉馏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情脱羡,我是刑警寧澤萝究,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站锉罐,受9級特大地震影響帆竹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜脓规,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一栽连、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧侨舆,春花似錦秒紧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至臭笆,卻和暖如春叙淌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背愁铺。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工鹰霍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茵乱。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓茂洒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親似将。 傳聞我的和親對象是個殘疾皇子获黔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容