国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【源碼系列#05】Vue3響應(yīng)式原理(Ref)

這篇具有很好參考價值的文章主要介紹了【源碼系列#05】Vue3響應(yīng)式原理(Ref)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Ref & ShallowRef

ref:接受一個參數(shù)值并返回一個響應(yīng)式且可改變的 ref 對象。ref 對象擁有一個指向內(nèi)部值的單一屬性 .value

可以將 ref 看成 reactive 的一個變形版本,這是由于 reactive 內(nèi)部采用 Proxy 來實現(xiàn),而 Proxy 只接受對象作為入?yún)?,這才有了 ref 來解決值類型的數(shù)據(jù)響應(yīng),如果傳入 ref 的是一個對象,內(nèi)部也會調(diào)用 reactive 方法進行深層響應(yīng)轉(zhuǎn)換

const count = ref(0)
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

shallowRef:ref() 的淺層作用形式。和 ref() 不同,淺層 ref 的內(nèi)部值將會原樣存儲和暴露,并且不會被深層遞歸地轉(zhuǎn)為響應(yīng)式。只有對 .value 的訪問是響應(yīng)式的。

const state = shallowRef({ count: 1 })

// 不會觸發(fā)更改
state.value.count = 2

// 會觸發(fā)更改
state.value = { count: 2 }

源碼實現(xiàn)

  • @issue1 如果是對象和數(shù)組,則調(diào)用 reactive方法 轉(zhuǎn)化為響應(yīng)式對象(ref會轉(zhuǎn)換,shallowRef不會轉(zhuǎn)換)
  • @issue2 getter 取值的時候收集依賴
  • @issue3 setter 設(shè)置值的時候觸發(fā)依賴
/**
 * @desc 如果是對象和數(shù)組,則轉(zhuǎn)化為響應(yīng)式對象
 */
function toReactive(value) {
  return isObject(value) ? reactive(value) : value
}

/**
 * @desc RefImpl
 * @issue1 如果是對象和數(shù)組,則轉(zhuǎn)化為響應(yīng)式對象
 */
class RefImpl {
  // ref標(biāo)識
  public __v_isRef = true
  // 存儲effect
  public dep = new Set()
  public _value
  constructor(public rawValue, public _shallow) {
    // @issue1
    this._value = _shallow ? rawValue : toReactive(rawValue)
  }
  get value() {
    // 取值的時候收集依賴
    trackEffects(this.dep)
    return this._value
  }
  set value(newValue) {
    // 新舊值不相等
    if (newValue !== this.rawValue) {
      // @issue1
      this._value = this._shallow ? newValue : toReactive(newValue)
      this.rawValue = newValue
      // 設(shè)置值的時候觸發(fā)依賴
      triggerEffects(this.dep)
    }
  }
}


// 接受一個內(nèi)部值,返回一個響應(yīng)式的、可更改的 ref 對象,此對象只有一個指向其內(nèi)部值的屬性 .value。
export function ref(value) {
  return new RefImpl(value)
}

測試代碼

/**
 * 1. Ref
 **/
const person = ref({
  name: '柏成',
  age: 25,
})
effect(() => {
  app.innerHTML = person.value.name
})

setTimeout(() => {
  person.value.name = '柏成2號' // 會觸發(fā)更改
}, 1000)

/**
 * 2. shallowRef
 */
const person = shallowRef({
  name: '柏成',
  age: 25,
})
effect(() => {
  app.innerHTML = person.value.name
})

setTimeout(() => {
  person.value.name = '柏成2號' // 不會觸發(fā)更改
}, 1000)

setTimeout(() => {
  person.value = {
    name: '柏成9號' // 會觸發(fā)更改
  }
}, 2000)

toRef & toRefs

toRef:基于響應(yīng)式對象上的一個屬性,創(chuàng)建一個對應(yīng)的 ref。這樣創(chuàng)建的 ref 與其源屬性保持同步:改變源屬性的值將更新 ref 的值,反之亦然。

const state = reactive({
  foo: 1,
  bar: 2
})

const fooRef = toRef(state, 'foo')

// 更改該 ref 會更新源屬性
fooRef.value++
console.log(state.foo) // 2

// 更改源屬性也會更新該 ref
state.foo++
console.log(fooRef.value) // 3

toRefs:將一個響應(yīng)式對象轉(zhuǎn)換為一個普通對象,這個普通對象的每個屬性都是指向源對象相應(yīng)屬性的 ref。每個單獨的 ref 都是使用 toRef() 創(chuàng)建的。

const state = reactive({
  foo: 1,
  bar: 2
})

const stateAsRefs = toRefs(state)

// 這個 ref 和源屬性已經(jīng) “鏈接上了”
state.foo++
console.log(stateAsRefs.foo.value) // 2

stateAsRefs.foo.value++
console.log(state.foo) // 3

源碼實現(xiàn)

class ObjectRefImpl {
  // 只是將.value屬性代理到原始類型上
  constructor(public object, public key) {}
  
  get value() {
    return this.object[this.key]
  }
  
  set value(newValue) {
    this.object[this.key] = newValue
  }
}

// 基于響應(yīng)式對象上的一個屬性,創(chuàng)建一個對應(yīng)的 ref。這樣創(chuàng)建的 ref 與其源屬性保持同步:改變源屬性的值將更新 ref 的值,反之亦然。
export function toRef(object, key) {
  return new ObjectRefImpl(object, key)
}

// 將一個響應(yīng)式對象轉(zhuǎn)換為一個普通對象,這個普通對象的每個屬性都是指向源對象相應(yīng)屬性的 ref。每個單獨的 ref 都是使用 toRef() 創(chuàng)建的。
export function toRefs(object) {
  const result = isArray(object) ? new Array(object.length) : {}

  for (let key in object) {
    result[key] = toRef(object, key)
  }

  return result
}

測試代碼

// 對象
const person = reactive({
  name: '柏成',
  age: 18
})
// 數(shù)組
const numbers = reactive([1, 2, 3, 4, 5])

// 注意!直接解構(gòu)后會丟失響應(yīng)性的特點?。?!
// let { name, age } = person

const {
  name,
  age
} = toRefs(person)
const [first] = toRefs(numbers)

effect(() => {
  app.innerHTML = `${name.value},${age.value}歲。第一個數(shù)字為${first.value}。`
})

setTimeout(() => {
  name.value = '柏成9號'
  first.value = 999
}, 1000)

自動脫ref

在js中訪問ref時需要.value獲取,但是在模版中卻可以直接取值,不需要加.value!這里就用到了 proxyRefs 自動脫ref方法文章來源地址http://www.zghlxwxcb.cn/news/detail-776637.html

源碼實現(xiàn)

export function proxyRefs(object) {
  return new Proxy(object, {
    // 代理的思想,如果是ref 則取ref.value
    get(target, key, recevier) {
      let r = Reflect.get(target, key, recevier)
      return r.__v_isRef ? r.value : r
    },
    // 設(shè)置的時候如果是ref,則給ref.value賦值
    set(target, key, value, recevier) {
      let oldValue = target[key]
      if (oldValue.__v_isRef) {
        oldValue.value = value
        return true
      } else {
        return Reflect.set(target, key, value, recevier)
      }
    },
  })
}

測試代碼

const name = ref('柏成')
const age = ref('24')

const person = proxyRefs({
  name,
  age,
  sex: '男'
})

effect(() => {
  app.innerHTML = `${person.name},${person.age}歲。性別${person.sex}。`
})

setTimeout(() => {
  name.value = '柏成9號'
}, 1000)

到了這里,關(guān)于【源碼系列#05】Vue3響應(yīng)式原理(Ref)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • vue3中的ref、isRef、shallowRef、triggerRef和customRef

    vue3中的ref、isRef、shallowRef、triggerRef和customRef

    接受一個參數(shù)值并返回一個響應(yīng)式且可改變的 ref 對象。 ref 對象擁有一個指向內(nèi)部值的單一屬性 .value property ,指向內(nèi)部值。 例:此時,頁面上的 str1 也跟著變化 使用 ref 獲取 dom 元素: ?結(jié)果: 檢查一個對象是否為 ? ref ? 包裝過的對象。 創(chuàng)建一個跟蹤自身 .value 變化的

    2024年04月29日
    瀏覽(32)
  • Vue3 ref響應(yīng)式變量詳解

    在Vue 3中,ref是一個函數(shù),用于創(chuàng)建響應(yīng)式數(shù)據(jù)。它接受一個初始值作為參數(shù),并返回一個可變的響應(yīng)式對象。 使用ref創(chuàng)建的響應(yīng)式對象可以直接在模板中使用,并且當(dāng)其值發(fā)生變化時,相關(guān)的組件會自動重新渲染。與Vue 2中的data選項不同,Vue 3推薦使用ref來創(chuàng)建響應(yīng)式數(shù)據(jù)

    2024年02月09日
    瀏覽(16)
  • vue3-響應(yīng)式基礎(chǔ)之ref

    ref() 在組合式 API 中,推薦使用 ref() 函數(shù)來聲明響應(yīng)式狀態(tài): ref() 接收參數(shù),并將其包裹在一個帶有 .value 屬性的 ref 對象中返回: 形式1 setup() 函數(shù) 要在組件模板中訪問 ref,請從組件的 setup() 函數(shù)中聲明并返回它們: 注意,在模板中使用 ref 時,我們不需要附加 .value。為了

    2024年01月18日
    瀏覽(20)
  • 【手撕源碼】vue3響應(yīng)式原理解析(文末抽獎)

    【手撕源碼】vue3響應(yīng)式原理解析(文末抽獎)

    ?? 個人主頁: 不叫貓先生 ???♂? 作者簡介:2022年度博客之星前端領(lǐng)域TOP 2,前端領(lǐng)域優(yōu)質(zhì)作者、阿里云專家博主,專注于前端各領(lǐng)域技術(shù),共同學(xué)習(xí)共同進步,一起加油呀! ??優(yōu)質(zhì)專欄:vue3從入門到精通、TypeScript從入門到實踐 ?? 資料領(lǐng)?。呵岸诉M階資料以及文中源

    2024年02月03日
    瀏覽(21)
  • 前端Vue篇之Vue3響應(yīng)式:Ref和Reactive

    在Vue3中,響應(yīng)式編程是非常重要的概念,其中 Ref 和 Reactive 是兩個關(guān)鍵的API。 Ref : Ref 用于創(chuàng)建一個響應(yīng)式的基本數(shù)據(jù)類型,比如數(shù)字、字符串等。它將普通的數(shù)據(jù)變成響應(yīng)式數(shù)據(jù),可以監(jiān)聽數(shù)據(jù)的變化。使用 Ref 時,我們可以通過 .value 來訪問和修改數(shù)據(jù)的值。 Reactive :

    2024年04月25日
    瀏覽(25)
  • vue3 ref reactive響應(yīng)式數(shù)據(jù) 賦值的問題

    vue3 ref reactive響應(yīng)式數(shù)據(jù) 賦值的問題

    doing 遇見就記錄,最后更新時間23.8.30 錯誤示范:直接賦值 以數(shù)組為例,對象也是一樣的操作。 ref 定義的屬性等價于 reactive({value:xxx}) ,所以 reactive、ref 直接重新賦值丟失響應(yīng)是因為引用地址變了 正確寫法 方法1: ref.value ,代碼中更為清晰地表明響應(yīng)式數(shù)據(jù) 方法2:包一層

    2024年02月10日
    瀏覽(27)
  • 【Vue3】使用ref與reactive創(chuàng)建響應(yīng)式對象

    【Vue3】使用ref與reactive創(chuàng)建響應(yīng)式對象

    ??????歡迎來到我的博客,你將找到有關(guān)如何使用技術(shù)解決問題的文章,也會找到某個技術(shù)的學(xué)習(xí)路線。無論你是何種職業(yè),我都希望我的博客對你有所幫助。最后不要忘記訂閱我的博客以獲取最新文章,也歡迎在文章下方留下你的評論和反饋。我期待著與你分享知識、互

    2024年02月21日
    瀏覽(23)
  • Vue3通透教程【五】Vue3中的響應(yīng)式數(shù)據(jù) reactive函數(shù)、ref函數(shù)

    專欄介紹: 涼哥作為 Vue 的忠實粉絲輸出過大量的 Vue 文章,應(yīng)粉絲要求開始更新 Vue3 的相關(guān)技術(shù)文章,Vue 框架目前的地位大家應(yīng)該都曉得,所謂三大框架使用人數(shù)最多,公司選型最多的框架,涼哥之前在文章中也提到過就是 Vue 框架之所以火起來的原因,和 Vue 框架相比其他

    2024年01月24日
    瀏覽(26)
  • Vue3中的Ref與Reactive:深入理解響應(yīng)式編程

    Vue 3是一個功能強大的前端框架,它引入了一些令人興奮的新特性,其中最引人注目的是 ref 和 reactive 。這兩個API是Vue 3中響應(yīng)式編程的核心,本文將深入探討它們的用法和差異。 在Vue中,響應(yīng)式編程是一種使數(shù)據(jù)與UI保持同步的方式。當(dāng)數(shù)據(jù)變化時,UI會自動更新,反之亦然

    2024年02月08日
    瀏覽(31)
  • 關(guān)于 Vue3 響應(yīng)式 API 以及 reactive 和 ref 的用法

    關(guān)于 Vue3 響應(yīng)式 API 以及 reactive 和 ref 的用法

    這篇文章記錄一下 Vue3 響應(yīng)式的內(nèi)容,其中還包括了 reactive 和 ref 的用法。響應(yīng)式是一種允許以聲明式的方式去適應(yīng)變化的編程范例,接下來我們一起看看。 Vue 框架的特點之一就是響應(yīng)式。 Vue 2.x 是基于 Object.defineProperty() 方法實現(xiàn)響應(yīng)式。但是 Object.defineProperty() 方法有一定

    2024年02月12日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包