欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

vue3中的reactive()怎么使用

本篇內(nèi)容介紹了“vue3中的reactive()怎么使用”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),玄武企業(yè)網(wǎng)站建設(shè),玄武品牌網(wǎng)站建設(shè),網(wǎng)站定制,玄武網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,玄武網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

調(diào)試版本為3.2.45

  • 什么是reactive?

    reactive是Vue3中提供實(shí)現(xiàn)響應(yīng)式數(shù)據(jù)的方法.

    在Vue2中響應(yīng)式數(shù)據(jù)是通過(guò)defineProperty來(lái)實(shí)現(xiàn)的.

    而在Vue3響應(yīng)式數(shù)據(jù)是通過(guò)ES6的Proxy來(lái)實(shí)現(xiàn)的

  • reactive注意點(diǎn)

    reactive參數(shù)必須是對(duì)象(json/arr)

    如果給reactive傳遞了其他對(duì)象,默認(rèn)情況下修改對(duì)象,界面不會(huì)自動(dòng)更新,如果想更新,可以通過(guò)重新賦值的方式。

<script setup>
import {reactive} from 'vue'
const data = reactive({ //定義對(duì)象
  name:'測(cè)試',
  age:10
})
const num = reactive(1)//定義基本數(shù)據(jù)類型
console.log(data)//便于定位到調(diào)試位置
</script>
<template>
<div>
<h2>{{ data.name }}</h2>
</div>
</template>

<style scoped></style>

設(shè)置斷點(diǎn)

vue3中的reactive()怎么使用

vue3中的reactive()怎么使用

開始調(diào)試

接下來(lái)我們可以開始調(diào)試了,設(shè)置好斷點(diǎn)后,只要重新刷新頁(yè)面就可以進(jìn)入調(diào)試界面。

復(fù)雜數(shù)據(jù)類型

我們先調(diào)試簡(jiǎn)單的基本數(shù)據(jù)類型

vue3中的reactive()怎么使用1.

/*1.初始進(jìn)來(lái)函數(shù),判斷目標(biāo)對(duì)象target是否為只讀對(duì)象,如果是直接返回*/
function reactive(target) {
    // if trying to observe a readonly proxy, return the readonly version.
    if (isReadonly(target)) {
        return target;
    }
    //創(chuàng)建一個(gè)reactive對(duì)象,五個(gè)參數(shù)后續(xù)會(huì)講解
    return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
}


/*2.判斷是來(lái)判斷target是否為只讀。*/
function isReadonly(value) {
    return !!(value && value["__v_isReadonly" /* ReactiveFlags.IS_READONLY */]);
}

/*3.創(chuàng)建一個(gè)reactive對(duì)象*/
/*createReactiveObject接收五個(gè)參數(shù):
target被代理的對(duì)象,
isReadonl是不是只讀的,
baseHandlers proxy的捕獲器,
collectionHandlers針對(duì)集合的proxy捕獲器,
proxyMap一個(gè)用于緩存proxy的`WeakMap`對(duì)象*/
function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
//如果target不是對(duì)象則提示并返回
/*這里會(huì)跳轉(zhuǎn)到如下方法
判斷是否原始值是否為object類型 
const isObject = (val) => val !== null && typeof val === 'object';
*/
    if (!isObject(target)) {
        if ((process.env.NODE_ENV !== 'production')) {
            console.warn(`value cannot be made reactive: ${String(target)}`);
        }
        return target;
    }
    // 如果target已經(jīng)是proxy是代理對(duì)象則直接返回.
    if (target["__v_raw" /* ReactiveFlags.RAW */] &&
        !(isReadonly && target["__v_isReactive" /* ReactiveFlags.IS_REACTIVE */])) {
        return target;
    }
    // 從proxyMap中獲取緩存的proxy對(duì)象,如果存在的話,直接返回proxyMap中對(duì)應(yīng)的proxy。否則創(chuàng)建proxy。
    const existingProxy = proxyMap.get(target);
    if (existingProxy) {
        return existingProxy;
    }
    // 并不是任何對(duì)象都可以被proxy所代理。這里會(huì)通過(guò)getTargetType方法來(lái)進(jìn)行判斷。
    const targetType = getTargetType(target);
    //當(dāng)類型值判斷出是不能代理的類型則直接返回
    if (targetType === 0 /* TargetType.INVALID */) {
        return target;
    }
    //通過(guò)使用Proxy函數(shù)劫持target對(duì)象,返回的結(jié)果即為響應(yīng)式對(duì)象了。這里的處理函數(shù)會(huì)根據(jù)target對(duì)象不同而不同(這兩個(gè)函數(shù)都是參數(shù)傳入的):
    //Object或者Array的處理函數(shù)是collectionHandlers;
    //Map,Set,WeakMap,WeakSet的處理函數(shù)是baseHandlers;
    const proxy = new Proxy(target, targetType === 2 /* TargetType.COLLECTION */ ? collectionHandlers : baseHandlers);
    proxyMap.set(target, proxy);
    return proxy;
}

getTargetType方法調(diào)用流程

//1.進(jìn)入判斷如果value有__v_skip屬性且為true或?qū)ο笫强赏卣箘t返回0,否則走類型判斷函數(shù)
function getTargetType(value) {
//Object.isExtensible() 方法判斷一個(gè)對(duì)象是否是可擴(kuò)展的(是否可以在它上面添加新的屬性)。
    return value["__v_skip" /* ReactiveFlags.SKIP */] || !Object.isExtensible(value)
        ? 0 /* TargetType.INVALID */
        : targetTypeMap(toRawType(value));
}
//2.這里通過(guò)Object.prototype.toString.call(obj)來(lái)判斷數(shù)據(jù)類型
const toRawType = (value) => {
    // extract "RawType" from strings like "[object RawType]"
    return toTypeString(value).slice(8, -1);
};
const toTypeString = (value) => objectToString.call(value);
//3.這里rawType是為'Object'所以會(huì)返回1
function targetTypeMap(rawType) {
    switch (rawType) {
        case 'Object':
        case 'Array':
            return 1 /* TargetType.COMMON */;
        case 'Map':
        case 'Set':
        case 'WeakMap':
        case 'WeakSet':
            return 2 /* TargetType.COLLECTION */;
        default:
            return 0 /* TargetType.INVALID */;//返回0說(shuō)明除前面的類型外其他都不能被代理,如Date,RegExp,Promise等
    }
}

createReactiveObject方法中const proxy = new Proxy(target, targetType === 2 /* TargetType.COLLECTION */ ? collectionHandlers : baseHandlers);這一條語(yǔ)句中,第二個(gè)參數(shù)判斷target是否為Map或者Set類型。從而使用不同的handler來(lái)進(jìn)行依賴收集。

在調(diào)試的文件node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js中,我們從reactive函數(shù)的createReactiveObject函數(shù)調(diào)用的其中兩個(gè)參數(shù)mutableHandlersmutableCollectionHandlers開始往上查詢

mutableHandlers的實(shí)現(xiàn)

const mutableHandlers = {
    get,// 獲取值的攔截,訪問(wèn)對(duì)象時(shí)會(huì)觸發(fā)
    set,// 更新值的攔截,設(shè)置對(duì)象屬性會(huì)觸發(fā)
    deleteProperty,// 刪除攔截,刪除對(duì)象屬性會(huì)觸發(fā)
    has,// 綁定訪問(wèn)對(duì)象時(shí)會(huì)攔截,in操作符會(huì)觸發(fā)
    ownKeys// 獲取屬性key列表
};

function deleteProperty(target, key) {
    // key是否是target自身的屬性
    const hadKey = hasOwn(target, key);
    // 舊值
    const oldValue = target[key];
    // 調(diào)用Reflect.deleteProperty從target上刪除屬性
    const result = Reflect.deleteProperty(target, key);
    // 如果刪除成功并且target自身有key,則觸發(fā)依賴
    if (result && hadKey) {
        trigger(target, "delete" /* TriggerOpTypes.DELETE */, key, undefined, oldValue);
    }
    return result;
}
//
function has(target, key) {
    //檢查目標(biāo)對(duì)象是否存在此屬性。
    const result = Reflect.has(target, key);
    // key不是symbol類型或不是symbol的內(nèi)置屬性,進(jìn)行依賴收集
    if (!isSymbol(key) || !builtInSymbols.has(key)) {
        track(target, "has" /* TrackOpTypes.HAS */, key);
    }
    return result;
}
/*ownKeys可以攔截以下操作:
1.Object.keys()
2.Object.getOwnPropertyNames()
3.Object.getOwnPropertySymbols()
4.Reflect.ownKeys()操作*/
function ownKeys(target) {
    track(target, "iterate" /* TrackOpTypes.ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
    return Reflect.ownKeys(target);
}

get方法實(shí)現(xiàn)

const get = /*#__PURE__*/ createGetter();
/*傳遞兩個(gè)參數(shù)默認(rèn)都為false
isReadonly是否為只讀
shallow是否轉(zhuǎn)換為淺層響應(yīng),即Reactive---> shallowReactive,shallowReactive監(jiān)聽了第一層屬性的值,一旦發(fā)生改變,則更新視圖;其他層,雖然值發(fā)生了改變,但是視圖不會(huì)進(jìn)行更新
*/
function createGetter(isReadonly = false, shallow = false) {
    return function get(target, key, receiver) {
    //1.是否已被reactive相關(guān)api處理過(guò);
        if (key === "__v_isReactive" /* ReactiveFlags.IS_REACTIVE */) {
            return !isReadonly;
        }
     //2.是否被readonly相關(guān)api處理過(guò)
        else if (key === "__v_isReadonly" /* ReactiveFlags.IS_READONLY */) {
            return isReadonly;
        }
        else if (key === "__v_isShallow" /* ReactiveFlags.IS_SHALLOW */) {
            return shallow;
        }
      //3.檢測(cè)__v_raw屬性
        else if (key === "__v_raw" /* ReactiveFlags.RAW */ &&
            receiver ===
                (isReadonly
                    ? shallow
                        ? shallowReadonlyMap
                        : readonlyMap
                    : shallow
                        ? shallowReactiveMap
                        : reactiveMap).get(target)) {
            return target;
        }
      //4.如果target是數(shù)組,且命中了一些屬性,則執(zhí)行函數(shù)方法
        const targetIsArray = isArray(target);
        if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
            return Reflect.get(arrayInstrumentations, key, receiver);
        }
      //5.Reflect獲取值
        const res = Reflect.get(target, key, receiver);
      //6.判斷是否為特殊的屬性值
        if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
            return res;
        }
        if (!isReadonly) {
            track(target, "get" /* TrackOpTypes.GET */, key);
        }
        if (shallow) {
            return res;
        }
      //7.判斷是否為ref對(duì)象
        if (isRef(res)) {
            // ref unwrapping - skip unwrap for Array + integer key.
            return targetIsArray && isIntegerKey(key) ? res : res.value;
        }
      //8.判斷是否為對(duì)象
        if (isObject(res)) {
            // Convert returned value into a proxy as well. we do the isObject check
            // here to avoid invalid value warning. Also need to lazy access readonly
            // and reactive here to avoid circular dependency.
            return isReadonly ? readonly(res) : reactive(res);
        }
        return res;
    };
}

  • 檢測(cè)__v_isReactive屬性,如果為true,表示target已經(jīng)是一個(gè)響應(yīng)式對(duì)象了。

  • 依次檢測(cè)__v_isReadonly__v_isShallow屬性,判斷是否為只讀和淺層響應(yīng),如果是則返回對(duì)應(yīng)包裝過(guò)的target。

  • 檢測(cè)__v_raw屬性,這里是三元的嵌套,主要判斷原始數(shù)據(jù)是否為只讀或者淺層響應(yīng),然后在對(duì)應(yīng)的Map里面尋找是否有該目標(biāo)對(duì)象,如果都為true則說(shuō)明target已經(jīng)為響應(yīng)式對(duì)象。

  • 如果target是數(shù)組,需要對(duì)一些方法(針對(duì)includesindexOf、lastIndexOf、pushpop、shift、unshift、splice)進(jìn)行特殊處理。并對(duì)數(shù)組的每個(gè)元素執(zhí)行收集依賴,然后通過(guò)Reflect獲取數(shù)組函數(shù)的值。

  • Reflect獲取值。

  • 判斷是否為特殊的屬性值,symbol, __proto__,__v_isRef__isVue, 如果是直接返回前面得到的res,不做后續(xù)處理;

  • 如果為ref對(duì)象,target不是數(shù)組的情況下,會(huì)自動(dòng)解包。

  • 如果resObject,進(jìn)行深層響應(yīng)式處理。從這里就能看出,Proxy是懶惰式的創(chuàng)建響應(yīng)式對(duì)象,只有訪問(wèn)對(duì)應(yīng)的key,才會(huì)繼續(xù)創(chuàng)建響應(yīng)式對(duì)象,否則不用創(chuàng)建。

set方法實(shí)現(xiàn)

例子:data.name='2'

const set = /*#__PURE__*/ createSetter();
  //shallow是否轉(zhuǎn)換為淺層響應(yīng),默認(rèn)為false
function createSetter(shallow = false) {
    //1.傳遞四個(gè)參數(shù)
    return function set(target, key, value, receiver) {
        let oldValue = target[key];
        //首先獲取舊值,如果舊值是ref類型,且新值不是ref類型,則不允許修改
        if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) {
            return false;
        }
     //2.根據(jù)傳遞的shallow參數(shù),來(lái)執(zhí)行之后的操作
        if (!shallow) {
            if (!isShallow(value) && !isReadonly(value)) {
                oldValue = toRaw(oldValue);
                value = toRaw(value);
            }
            if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
                oldValue.value = value;
                return true;
            }
        }
      //3.檢測(cè)key是不是target本身的屬性
        const hadKey = isArray(target) && isIntegerKey(key)
            ? Number(key) < target.length
            : hasOwn(target, key);
        //利用Reflect.set()來(lái)修改值,返回一個(gè)Boolean值表明是否成功設(shè)置屬性
        //Reflect.set(設(shè)置屬性的目標(biāo)對(duì)象, 設(shè)置的屬性的名稱, 設(shè)置的值, 如果遇到 `setter`,`receiver`則為`setter`調(diào)用時(shí)的`this`值)
        const result = Reflect.set(target, key, value, receiver);
        // 如果目標(biāo)是原始原型鏈中的某個(gè)元素,則不要觸發(fā)
        if (target === toRaw(receiver)) {
        //如果不是target本身的屬性那么說(shuō)明執(zhí)行的是'add'操作,增加屬性
            if (!hadKey) {
                trigger(target, "add" /* TriggerOpTypes.ADD */, key, value);
            }
      //4.比較新舊值,是否觸發(fā)依賴
            else if (hasChanged(value, oldValue)) {
      //5.觸發(fā)依賴
                trigger(target, "set" /* TriggerOpTypes.SET */, key, value, oldValue);
            }
        }
        return result;
    };
}

1、以data.name='2'這段代碼為例,四個(gè)參數(shù)分別為:

target:目標(biāo)對(duì)象,即target={"name": "測(cè)試","age": 10}(此處為普通對(duì)象)

key:修改的對(duì)應(yīng)key,即key: "name"

value:修改的值,即value: "2"

receiver:目標(biāo)對(duì)象的代理。即receiver=Proxy {"name": "測(cè)試","age": 10}

2、shallow為false的時(shí)候。

第一個(gè)判斷:如果新值不是淺層響應(yīng)式并且不是readonly,新舊值取其對(duì)應(yīng)的原始值。

第二個(gè)判斷:如果target不是數(shù)組并且舊值是ref類型,新值不是ref類型,直接修改oldValue.value為value

3.檢測(cè)key是不是target本身的屬性。這里的hadKey有兩個(gè)方法,isArray就不解釋,就是判斷是否為數(shù)組

isIntegerKey:判斷是不是數(shù)字型的字符串key值

//判斷參數(shù)是否為string類型,是則返回true
const isString = (val) => typeof val === 'string';
//如果參數(shù)是string類型并且不是'NaN',且排除-值(排除負(fù)數(shù)),然后將 key 轉(zhuǎn)換成數(shù)字再隱式轉(zhuǎn)換為字符串,與原 key 對(duì)比
const isIntegerKey = (key) => isString(key) &&
    key !== 'NaN' &&
    key[0] !== '-' &&
    '' + parseInt(key, 10) === key;

4.比較新舊值,如果新舊值不同,則觸發(fā)依賴進(jìn)行更新

hasChanged方法

//Object.is()方法判斷兩個(gè)值是否是相同的值。
const hasChanged = (value, oldValue) => !Object.is(value, oldValue);

5.觸發(fā)依賴,這里太過(guò)復(fù)雜,筆者也沒搞懂,如果有興趣的讀者可自行去調(diào)試

<script setup>
import { reactive } from "vue";
const data = reactive({
  name: "測(cè)試",
  age: 10,
});

data.name='1'//這里并未收集依賴,在處理完 createSetupContext 的上下文后,組件會(huì)停止依賴收集,并且開始執(zhí)行 setup 函數(shù)。具體原因有興趣的讀者可以自行去了解
const testClick = ()=>{
  data.name='test'
}
</script>
<template>
  <div>
    <h2>{{ data.name }}</h2>
    <el-button @click="testClick">Click</el-button>
  </div>
</template>

<style scoped></style>

基本數(shù)據(jù)類型

const num = reactive(2)

這里比較簡(jiǎn)單,在createReactiveObject函數(shù)方法里面:

if (!isObject(target)) {
        if ((process.env.NODE_ENV !== 'production')) {
            console.warn(`value cannot be made reactive: ${String(target)}`);
        }
        return target;
    }

vue3中的reactive()怎么使用

因?yàn)榕袛囝愋筒皇菍?duì)象,所以會(huì)在控制臺(tái)打印出警告,并且直接返回原數(shù)據(jù)

proxy對(duì)象

<script>
const data = reactive({
  name: "測(cè)試",
  age: 10,
});
const num = reactive(data)//定義一個(gè)已經(jīng)是響應(yīng)式對(duì)象
</script>

1.調(diào)試開始進(jìn)來(lái)reactive函數(shù),然后會(huì)經(jīng)過(guò)isReadonly函數(shù),這里跟前面不同的是,target是一個(gè)proxy對(duì)象,它已經(jīng)被代理過(guò)有set,get等handler。所以在isReadonly函數(shù)讀取target的時(shí)候,target會(huì)進(jìn)行get函數(shù)的讀取操作。

function reactive(target) {
    // if trying to observe a readonly proxy, return the readonly version.
    if (isReadonly(target)) {
        return target;
    }
    return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
}

2.可以看到get傳入的參數(shù)有個(gè)key="__v_isReadonly",這里的isReadonly返回是false,接下來(lái)進(jìn)入createReactiveObject函數(shù)

這里說(shuō)明下,在本次調(diào)試中常見的vue里面定義的私有屬性有:

  • __v_skip:是否無(wú)效標(biāo)識(shí),用于跳過(guò)監(jiān)聽

  • __v_isReactive:是否已被reactive相關(guān)api處理過(guò)

  • __v_isReadonly:是否被readonly相關(guān)api處理過(guò)

  • __v_isShallow:是否為淺層響應(yīng)式對(duì)象

  • __v_raw:當(dāng)前代理對(duì)象的源對(duì)象,即target

vue3中的reactive()怎么使用

3.在createReactiveObject函數(shù)中,經(jīng)過(guò)target["__v_isReactive"]的時(shí)候會(huì)觸發(fā)target的get函數(shù),這時(shí)候get函數(shù)傳入的參數(shù)中key='__v_raw'

    if (target["__v_raw" /* ReactiveFlags.RAW */] &&
        !(isReadonly && target["__v_isReactive" /* ReactiveFlags.IS_REACTIVE */])) {
                return target;
    }

vue3中的reactive()怎么使用

由上圖可知我們檢測(cè)target即已定義過(guò)的proxy對(duì)象,被reactiveapi處理過(guò)就會(huì)有__v_raw私有屬性,然后再進(jìn)行receiver的判斷,判斷target是否為只讀或淺層響應(yīng)。如果都不是則從緩存proxy的WeakMap對(duì)象中獲取該元素。最后直接返回target的原始數(shù)據(jù)(未被proxy代理過(guò))。

最后回到之前的判斷,由下圖可知,target__v_raw屬性存在,isReadonly為false,__v_isReactive的值為true,可以說(shuō)明reactive函數(shù)需要處理的對(duì)象是一個(gè)被reactiveAPI處理過(guò)的對(duì)象,然后直接返回該對(duì)象的原始數(shù)據(jù)。

vue3中的reactive()怎么使用

ref類型

經(jīng)過(guò)ref函數(shù)處理,其本質(zhì)也是一個(gè)對(duì)象,所以使用reactive函數(shù)處理ref類型就跟處理復(fù)雜數(shù)據(jù)類型一樣過(guò)程。

(開發(fā)中應(yīng)該不會(huì)有這種嵌套行為吧,這里只是為了測(cè)試多樣化)。

<script setup>
import { reactive,ref } from "vue";
const data = reactive({
  name: "測(cè)試",
  age: 10,
});
const numRef = ref(1)
const dataRef = ref({
  name: "測(cè)試2",
  age: 20,
})
const num = reactive(numRef)
const dataReactive = reactive(dataRef)
console.log('data',data)
console.log('numRef',numRef)
console.log('num',num)
console.log('dataRef',dataRef)
console.log('dataReactive',dataReactive)
</script>

vue3中的reactive()怎么使用

Map類型和Set類型

  • Map 類型是鍵值對(duì)的有序列表,而鍵和值都可以是任意類型。

  • SetMap類似,也是一組key的集合,但不存儲(chǔ)value。由于key不能重復(fù),所以,在Set中,沒有重復(fù)的key。

<script setup>
import { reactive } from "vue";
const mapData = new Map();
mapData.set('name','張三')
const setData = new Set([1,2,3,1,1])
console.log(mapData)
console.log(setData)
const mapReactive = reactive(mapData)
console.log(mapReactive)
</script>

vue3中的reactive()怎么使用

由上圖可知Map結(jié)構(gòu)和Set結(jié)構(gòu)使用typeof判斷是object,所有流程前面會(huì)跟復(fù)雜數(shù)據(jù)類型一樣,知道在createReactiveObject函數(shù)的getTargetType()函數(shù)開始不同。

getTargetType函數(shù)里面toRawType()判斷數(shù)據(jù)類型所用方法為Object.prototype.toString.call()

const targetType = getTargetType(target);

function getTargetType(value) {
    return value["__v_skip" /* ReactiveFlags.SKIP */] || !Object.isExtensible(value)
        ? 0 /* TargetType.INVALID */
        : targetTypeMap(toRawType(value));
}

function targetTypeMap(rawType) {//rawType="Map",這里返回值為2
    switch (rawType) {
        case 'Object':
        case 'Array':
            return 1 /* TargetType.COMMON */;
        case 'Map':
        case 'Set':
        case 'WeakMap':
        case 'WeakSet':
            return 2 /* TargetType.COLLECTION */;
        default:
            return 0 /* TargetType.INVALID */;
    }
}

這時(shí)候targetType=2,在createReactiveObject的函數(shù)中const proxy = new Proxy(target, targetType === 2 /* TargetType.COLLECTION */ ? collectionHandlers : baseHandlers);的三元表達(dá)式中可得知,這里的handlercollectionHandlers

網(wǎng)上查找可在reactive函數(shù)中return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);這條語(yǔ)句找到,當(dāng)rawType=1時(shí)handler是用mutableHandlers,rawType=1時(shí)是用mutableCollectionHandlers。

mutableCollectionHandlers方法:

const mutableCollectionHandlers = {
    get: /*#__PURE__*/ createInstrumentationGetter(false, false)
};

//解構(gòu)createInstrumentations
const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations();
//傳入兩個(gè)參數(shù),是否為可讀,是否為淺層響應(yīng)
function createInstrumentationGetter(isReadonly, shallow) {
    const instrumentations = shallow
        ? isReadonly
            ? shallowReadonlyInstrumentations
            : shallowInstrumentations
        : isReadonly
            ? readonlyInstrumentations
            : mutableInstrumentations;
    return (target, key, receiver) => {
        if (key === "__v_isReactive" /* ReactiveFlags.IS_REACTIVE */) {
            return !isReadonly;
        }
        else if (key === "__v_isReadonly" /* ReactiveFlags.IS_READONLY */) {
            return isReadonly;
        }
        else if (key === "__v_raw" /* ReactiveFlags.RAW */) {
            return target;
        }
        return Reflect.get(hasOwn(instrumentations, key) && key in target
            ? instrumentations
            : target, key, receiver);
    };
}
//篇幅問(wèn)題以及這方面筆者并未深入,所以就大概帶過(guò)
function createInstrumentations() {
//創(chuàng)建了四個(gè)對(duì)象,對(duì)象內(nèi)部有很多方法,其他去掉了,完整可自行去調(diào)試查看
    const mutableInstrumentations = {
        get(key) {
            return get$1(this, key);
        },
        get size() {
            return size(this);
        },
        has: has$1,
        add,
        set: set$1,
        delete: deleteEntry,
        clear,
        forEach: createForEach(false, false)
    };
    
    .................
    
    //通過(guò)createIterableMethod方法操作keys、values、entries、Symbol.iterator迭代器方法
    const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
    iteratorMethods.forEach(method => {
        mutableInstrumentations[method] = createIterableMethod(method, false, false);
        readonlyInstrumentations[method] = createIterableMethod(method, true, false);
        shallowInstrumentations[method] = createIterableMethod(method, false, true);
        shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
    });
    return [
        mutableInstrumentations,
        readonlyInstrumentations,
        shallowInstrumentations,
        shallowReadonlyInstrumentations
    ];
}

“vue3中的reactive()怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

網(wǎng)站名稱:vue3中的reactive()怎么使用
文章分享:http://aaarwkj.com/article0/jjhoio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、品牌網(wǎng)站設(shè)計(jì)建站公司、外貿(mào)建站、網(wǎng)站建設(shè)、動(dòng)態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司
成人性生交大片免费看多人| 亚洲精品一区二区三区高清| 日本高清久久一区二区三区| 黑人爆操中国女孩在线观看| 人妻人人澡人人添人人爽桃色| 亚洲精品一区二区三区小| 久草热不卡的av在线| 亚洲三级伦理在线视频| 成人性生交大片免费看多人| 亚洲熟妇av一区二区| 国产成人久久久精品一区| 日韩色图在线观看视频| 欧美日韩加勒比综合在线| 欧美日韩激情在线一区| 国产欧美日韩综合一区| 99久热在线精品视频| 亚洲国产高清第一第二区| 日韩av一区二区人妻| 国产中文字幕精品在线观看| 国产在线第一页第二页| 久久精品国产91麻豆| 色一区欧美一区亚洲一区| 免费黄片视频大全在线播放| 在线播放亚洲一区二区三区 | av久久精品在线观看| av影片免费网址大全| 久久中文字幕一区二区三区| 亚洲欧美熟妇欲乱又伦| 少妇毛片一区二区三区| 亚洲五月六月激情综合| 人人妻人人澡人人爽的视频| 亚洲欧美综合另类久久| 人人妻人人澡人人爽人人精品| 97在线资源视频播放| 日日夜夜添添精品视频| 日本福利影院在线观看| 91午夜精品亚洲一区二区三区| 精品视频一区二区三区中文字幕| av影片在线观看不卡| 欧美一区二区三区午夜| 一区二区蜜桃在线观看|