最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3中reactive與ref函數(shù)使用場景

 更新時(shí)間:2022年07月13日 09:18:31   作者:拜小白  
這篇文章主要為大家介紹了Vue3?中有場景是?reactive?能做而?ref?做不了的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

如果你使用過 Vue3,你知道的,在 Vue3 中有兩個(gè)非常常用的響應(yīng)式 API:reactive 和 ref。它們會把我們想要追蹤的數(shù)據(jù)變成響應(yīng)式。

而且我們在使用時(shí)一直被告知 ref 用于創(chuàng)建基礎(chǔ)類型的響應(yīng)式,也可以創(chuàng)建引用類型的響應(yīng)式。而對于引用類型,底層也是轉(zhuǎn)換為 reactive 來進(jìn)行響應(yīng)式處理。那既然這樣為撒還需要 reactive ,全部使用 ref 不就行了嗎?

雖然 ref 創(chuàng)建的響應(yīng)式數(shù)據(jù)在腳本中需要通過 .value 才能訪問到呀!但是這里肯定影響不大。并且在模板中會自動(dòng)添加上 .value,所以模板中不需要通過 .value 訪問。

既然這二者基本沒撒差別,但是還是暴露了 reactive 這個(gè) API,難道有什么場景是 reactive 能做而 ref 做不了的?

簡單了解 ref & reactive

我們先簡單了解一下這兩個(gè) API。

reactive

返回對象的響應(yīng)式副本,響應(yīng)式轉(zhuǎn)換是“深層”的——它影響所有嵌套 property。我們一般這樣寫。

const obj = reactive({ count: 0 })

并且可以直接使用。

const count = obj.count

ref

接受一個(gè)內(nèi)部值并返回一個(gè)響應(yīng)式且可變的 ref 對象。ref 對象僅有一個(gè) .value property,指向該內(nèi)部值。 我們一般是這樣寫。

const data = ref(xxx)

引用的時(shí)候,一般會通過data.value的方式引用。

const dataValue = data.value

通過跟蹤 Vue3 的源代碼可以證明,當(dāng)我們調(diào)用 ref 方法來定義響應(yīng)式數(shù)據(jù)時(shí),當(dāng)參數(shù)為對象類型時(shí),其實(shí)里面用的是 reactive 方法。也就是說上面的 data.value ,事實(shí)上是 reactive 方法創(chuàng)造出來的。

reactive 能做的 ref 也能做,并且還是用 reactive 做的

我們通過源碼來看看 ref 的源碼實(shí)現(xiàn)。

源碼分析版本:3.2.36

function ref(value) {
    return createRef(value, false);
}

ref 函數(shù)跳轉(zhuǎn)到 createRef 函數(shù)。

function createRef(rawValue, shallow) {
    ...
    return new RefImpl(rawValue, shallow);
}

createRef 函數(shù)返回的是 RefImpl 類的實(shí)例,換句話說,ref 創(chuàng)建出來的響應(yīng)式就是 RefImpl 實(shí)例對象。

const count = ref(1);
console.log(count);

我們重點(diǎn)來看看這個(gè) RefImpl 類。

class RefImpl {
    constructor(value, __v_isShallow) {
        ... 
        this._value = __v_isShallow ? value : toReactive(value);
    }
    get value() {
        trackRefValue(this);
        return this._value;
    }
    set value(newVal) {
        newVal = this.__v_isShallow ? newVal : toRaw(newVal);
        if (hasChanged(newVal, this._rawValue)) {
            this._rawValue = newVal;
            this._value = this.__v_isShallow ? newVal : toReactive(newVal);
            triggerRefValue(this, newVal);
        }
    }
}

__v_isShallow 參數(shù)在這里默認(rèn)是 false,這里也順帶講一嘴,當(dāng)我們在使用 shallowRef 時(shí),這個(gè)參數(shù)為 true。

function shallowRef(value) {
    return createRef(value, true);
}

Ref 與 Reactive 創(chuàng)建的都是遞歸響應(yīng)的,將每一層的 json 數(shù)據(jù)解析成一個(gè) proxy 對象,shallowRef 與 shallowReactive 創(chuàng)建的是非遞歸的響應(yīng)對象,shallowReactive 創(chuàng)建的數(shù)據(jù)第一層數(shù)據(jù)改變會重新渲染 dom。

 var state = shallowReactive({
    a:'a',
    gf:{
       b:'b',
       f:{
          c:'c',
          s:{d:'d'}
       }
    }
 });
// 改變第一層的數(shù)據(jù)會導(dǎo)致頁面重新渲染
state.a = '1'
// 如果不改變第一層,只改變其他的數(shù)據(jù)頁面不會重新渲染 
state.gf.b = 2

通過 shallowRef 創(chuàng)建的響應(yīng)式對象,需要修改整個(gè) value 才能重新渲染 dom。

var state = shallowRef({
   a:'a',
    gf:{
       b:'b',
       f:{
          c:'c',
          s:{d:'d'}
       }
    }
});
// 不會重新渲染
state.value.a = 1
// 要修改整個(gè) value 才能重新渲染
state.value = {
    a:'1',
    gf:{
       b:'2',
       f:{
          c:'3',
          s:{d:'d'}
       }
    }
}

如果想更新 shallowRef 的某一層數(shù)據(jù),并且想觸發(fā)渲染,可以使用 triggerRef。

var state = shallowRef({
   a:'a',
    gf:{
       b:'b',
       f:{
          c:'c',
          s:{d:'d'}
       }
    }
})
state.value.gf.f.s.d = 4
triggerRef(state)

所以這里會走到 toReactive(value) 函數(shù)。

const isObject = (val) => val !== null && typeof val === 'object';
const toReactive = (value) => isObject(value) ? reactive(value) : value;

可以看到,如果傳入的參數(shù)是一個(gè)對象的話,返回值將會繼續(xù)調(diào)用 reactive 方法來進(jìn)行包裹,reactive 最終會通過 Proxy 來進(jìn)行實(shí)現(xiàn)響應(yīng)攔截,返回的也是一個(gè) Proxy 對象,但在這里不重要,我們只需要知道當(dāng) ref 的參數(shù)為對象時(shí),用的就是 reactive 方法。

const data = reactive({
  count: 1,
});
console.log(data);
const data_ref = ref({
  count: 1,
});
console.log(data_ref);

結(jié)果顯然,讓對 ref 傳入對象作為參數(shù)時(shí)和傳入基本類型作為參數(shù)返回結(jié)果情況是不一樣的。

基本類型返回值value就是具體的值,對象類型返回值value是 reactive 方法創(chuàng)建的 proxy 對象。

通過源碼來看,其實(shí)也證明了,在 Vue3 中,如果是把對象類型的數(shù)據(jù)弄成響應(yīng)式,reactive 和 ref 都可以,且ref 內(nèi)部是通過r eactive 來支持的。

也就是說,你 reactive 能做的,我 ref 也能做。

ref 能做,但是 reactive 不能做

其實(shí)通過上面的例子就能知道有什么是 reactive 不能做的呢?很明顯,reactive 不支持對基本類型數(shù)據(jù)響應(yīng)式,也就是說基本類型數(shù)據(jù)不能直接作為 reactive 的參數(shù)來使用。

簡單看看源碼。

function reactive(target) {
    ...
    return createReactiveObject(...);
}

reactive 函數(shù)跳轉(zhuǎn)到 createReactiveObject 函數(shù)。

const isObject = (val) => val !== null && typeof val === 'object';
function createReactiveObject(...) {
    if (!isObject(target)) {
        {
            console.warn(`value cannot be made reactive: ${String(target)}`);
        }
        return target;
    }
    ...
    const proxy = new Proxy(...);
    proxyMap.set(target, proxy);
    return proxy;
}

createReactiveObject 一開始就會判斷 target 是否是對象,如果不是對象就會直接??提示返回。如果是對象就會把 target 用 Proxy 變成響應(yīng)式對象。

const data = reactive(10);

總結(jié)

我們通過源碼來分析了兩個(gè)響應(yīng)式 API,發(fā)現(xiàn) Vue3 中有沒有 reactive 能做而 ref 做不了的場景?

結(jié)論是:沒有

簡單來說 ref 是在 reactive 上在進(jìn)行了封裝進(jìn)行了增強(qiáng),所以在 Vue3 中 reactive 能做的,ref 也能做,reactive 不能做的,ref 也能做。

參考

https://v3.cn.vuejs.org/api/refs-api.html#ref

https://v3.cn.vuejs.org/api/basic-reactivity.html

https://v3.cn.vuejs.org/guide/reactivity.html#什么是響應(yīng)性

https://github.com/vuejs/docs-next-zh-c

以上就是Vue3中reactive與ref函數(shù)使用場景的詳細(xì)內(nèi)容,更多關(guān)于Vue3 reactive ref函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue計(jì)算屬性與監(jiān)視屬性實(shí)現(xiàn)方法詳解

    Vue計(jì)算屬性與監(jiān)視屬性實(shí)現(xiàn)方法詳解

    最近在學(xué)習(xí)vue,學(xué)習(xí)中遇到了一些感覺挺重要的知識點(diǎn),感覺有必要整理下來,這篇文章主要給大家介紹了關(guān)于Vue.js中計(jì)算屬性、監(jiān)視屬性的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • Vue3中createWebHistory和createWebHashHistory的區(qū)別詳析

    Vue3中createWebHistory和createWebHashHistory的區(qū)別詳析

    這篇文章主要給大家介紹了關(guān)于Vue3中createWebHistory和createWebHashHistory區(qū)別的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-06-06
  • vue中的slot封裝組件彈窗

    vue中的slot封裝組件彈窗

    這篇文章主要介紹了vue中的slot封裝組件彈窗,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • vue項(xiàng)目打包清除console.log的四種方法總結(jié)

    vue項(xiàng)目打包清除console.log的四種方法總結(jié)

    大家在項(xiàng)目開發(fā)的時(shí)候,需要看看一些后端接口返回的結(jié)果,會多次使用console.log項(xiàng)目開發(fā)完成打包的時(shí)候,發(fā)現(xiàn)控制臺一堆的console.log,非常頭疼,下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目打包清除console.log的四種方法,需要的朋友可以參考下
    2023-04-04
  • 關(guān)于vue.js中實(shí)現(xiàn)方法內(nèi)某些代碼延時(shí)執(zhí)行

    關(guān)于vue.js中實(shí)現(xiàn)方法內(nèi)某些代碼延時(shí)執(zhí)行

    今天小編就為大家分享一篇關(guān)于vue.js中實(shí)現(xiàn)方法內(nèi)某些代碼延時(shí)執(zhí)行,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • Vue2.x-使用防抖以及節(jié)流的示例

    Vue2.x-使用防抖以及節(jié)流的示例

    這篇文章主要介紹了Vue2.x-使用防抖以及節(jié)流的示例,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下
    2021-03-03
  • vue中動(dòng)態(tài)組件使用及傳值方式

    vue中動(dòng)態(tài)組件使用及傳值方式

    這篇文章主要介紹了vue中動(dòng)態(tài)組件使用及傳值方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 使用vue2.0創(chuàng)建的項(xiàng)目的步驟方法

    使用vue2.0創(chuàng)建的項(xiàng)目的步驟方法

    這篇文章主要介紹了使用vue2.0創(chuàng)建的項(xiàng)目的步驟方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • vue如何使用router.meta.keepAlive對頁面進(jìn)行緩存

    vue如何使用router.meta.keepAlive對頁面進(jìn)行緩存

    這篇文章主要介紹了vue如何使用router.meta.keepAlive對頁面進(jìn)行緩存問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • vue filter 完美時(shí)間日期格式的代碼

    vue filter 完美時(shí)間日期格式的代碼

    這篇文章主要介紹了vue filter 完美時(shí)間日期格式的方法,文中給大家提到了vue filter方法-時(shí)間格式化 的代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2019-08-08

最新評論

尚志市| 天峨县| 托克逊县| 平远县| 金阳县| 泽普县| 武汉市| 保山市| 东辽县| 鹰潭市| 阿城市| 茂名市| 繁峙县| 杨浦区| 贵阳市| 河津市| 根河市| 邓州市| 阜城县| 万荣县| 永春县| 措勤县| 岐山县| 崇礼县| 普兰县| 时尚| 延津县| 黄石市| 汝城县| 宁蒗| 彭阳县| 礼泉县| 永寿县| 甘德县| 内乡县| 六枝特区| 惠水县| 葫芦岛市| 乌拉特中旗| 宜春市| 凤山市|