中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue3中reactive與ref函數使用場景是什么

發布時間:2022-07-13 14:08:53 來源:億速云 閱讀:365 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“Vue3中reactive與ref函數使用場景是什么”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Vue3中reactive與ref函數使用場景是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

    簡單了解 ref & reactive

    我們先簡單了解一下這兩個 API。

    reactive

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

    const obj = reactive({ count: 0 })

    并且可以直接使用。

    const count = obj.count

    ref

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

    const data = ref(xxx)

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

    const dataValue = data.value

    通過跟蹤 Vue3 的源代碼可以證明,當我們調用 ref 方法來定義響應式數據時,當參數為對象類型時,其實里面用的是 reactive 方法。也就是說上面的 data.value ,事實上是 reactive 方法創造出來的。

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

    我們通過源碼來看看 ref 的源碼實現。

    源碼分析版本:3.2.36

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

    ref 函數跳轉到 createRef 函數。

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

    createRef 函數返回的是 RefImpl 類的實例,換句話說,ref 創建出來的響應式就是 RefImpl 實例對象。

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

    Vue3中reactive與ref函數使用場景是什么

    我們重點來看看這個 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 參數在這里默認是 false,這里也順帶講一嘴,當我們在使用 shallowRef 時,這個參數為 true。

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

    Ref 與 Reactive 創建的都是遞歸響應的,將每一層的 json 數據解析成一個 proxy 對象,shallowRef 與 shallowReactive 創建的是非遞歸的響應對象,shallowReactive 創建的數據第一層數據改變會重新渲染 dom。

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

    通過 shallowRef 創建的響應式對象,需要修改整個 value 才能重新渲染 dom。

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

    如果想更新 shallowRef 的某一層數據,并且想觸發渲染,可以使用 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) 函數。

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

    可以看到,如果傳入的參數是一個對象的話,返回值將會繼續調用 reactive 方法來進行包裹,reactive 最終會通過 Proxy 來進行實現響應攔截,返回的也是一個 Proxy 對象,但在這里不重要,我們只需要知道當 ref 的參數為對象時,用的就是 reactive 方法。

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

    Vue3中reactive與ref函數使用場景是什么

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

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

    通過源碼來看,其實也證明了,在 Vue3 中,如果是把對象類型的數據弄成響應式,reactive 和 ref 都可以,且ref 內部是通過r eactive 來支持的。

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

    ref 能做,但是 reactive 不能做

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

    簡單看看源碼。

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

    reactive 函數跳轉到 createReactiveObject 函數。

    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 變成響應式對象。

    const data = reactive(10);

    Vue3中reactive與ref函數使用場景是什么

    讀到這里,這篇“Vue3中reactive與ref函數使用場景是什么”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    枣阳市| 桐乡市| 托克逊县| 大宁县| 城市| 土默特右旗| 宾川县| 花垣县| 丁青县| 罗甸县| 盐城市| 七台河市| 肥东县| 肃南| 静海县| 翁源县| 建阳市| 华亭县| 襄樊市| 墨竹工卡县| 沂南县| 秦安县| 崇明县| 红原县| 台北县| 舒兰市| 嘉善县| 舞钢市| 平舆县| 虞城县| 德钦县| 望谟县| 中江县| 开阳县| 青神县| 略阳县| 巴塘县| 谷城县| 友谊县| 临泽县| 博罗县|