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

溫馨提示×

溫馨提示×

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

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

vue3響應式實現readonly的方法是什么

發布時間:2023-03-06 17:29:01 來源:億速云 閱讀:131 作者:iii 欄目:開發技術

這篇文章主要介紹“vue3響應式實現readonly的方法是什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“vue3響應式實現readonly的方法是什么”文章能幫助大家解決問題。

readonly的實現

it("happy path", () => {
    console.warn = vi.fn();
    const original = {
      foo: 1,
    };
    const observed = readonly({
      foo: 1,
    });
    expect(original).not.toBe(observed);
    expect(observed.foo).toBe(1);
    //  set不起作用
    observed.foo = 2; 
    expect(observed.foo).toBe(1);
    //  當被set的時候,發出一個警告
    expect(console.warn).toBeCalled();
  });

其實與我們之前實現 reactive 十分的類似,區別只不過是set 的時候不要觸發trigger,而是警告。當然既然是不會被改變的,track 也是不必要的。

export function readonly(raw) { 
    return new Proxy(raw, { 
        get(target, key) { 
            const res = Reflect.get(target, key); 
            return res; 
        }, 
        set(target, key, newValue, receiver) {
            console.warn(
              `property: ${String(key)} can't be set, beacase ${target} is readonly.`
            );
            return true;
      },
    }); 
}
export function reactive(raw) { 
    return new Proxy(raw, { 
        get(target, key) { 
            const res = Reflect.get(target, key); 
            // 依賴收集 
            track(target, key); 
            return res; 
        }, 
        set(target, key, value) { 
            const res = Reflect.set(target, key, value); 
            // 觸發依賴 
            trigger(target, key); 
            return res; 
        }, 
    }); 
}

重構

可以看到,readonlyreactive 實現其實很類似,那我們可以重構一下,增強后續的拓展性。

至于我說的類似,指的是 new Proxy(target, handlers) 中的handlers(處理器對象)中的一些traps(捕獲器)。即get, set 這些方法。

我們可以通過工廠函數來創建那些traps函數,來簡化我們的代碼,提高可維護性。

另外,我們假定traps可以有工廠可以生產了,即handlers這部分相當于被定下來了,new Proxy 這部分也理應可以通過工廠函數創造出來。

我們先抽出一個公共的文件 baseHandler.ts

//  baseHanlder.ts
import { track, trigger } from "./effect";
//  get的工廠函數
function createGetter(isReadonly = false) {
  return function get(target, key) {
    const res = Reflect.get(target, key);
    if (!isReadonly) {
      track(target, key);
    }
    return res;
  };
}
function createSetter() {
  return function set(target, key, newValue, receiver) {
    const res = Reflect.set(target, key, newValue, receiver);
    trigger(target, key, type, newValue);
    return res;
  };
}
export const mutableHandler = {
  get: createGetter(),
  set: createSetter(),
};
export const readonlyHandler = {
  get: createGetter(),
  set(target, key, newValue, receiver) {
    console.warn(
      `property: ${String(key)} can't be set, beacase ${target} is readonly.`
    );
    return true;
};

然后是我們的reactive.ts

//  reactive.ts
import {
  mutableHandler,
  readonlyHandler,
} from "./baseHandlers";
//  proxy的工廠函數
function createReactiveObject(
  target,
  baseHandlers: ProxyHandler<any>
) {
  return new Proxy(target, baseHandlers);
}
export function reactive(target) {
  return createReactiveObject(target, mutableHandler);
}
export function readonly(target) {
  return createReactiveObject(target, readonlyHandler);
}

關于“vue3響應式實現readonly的方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

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

AI

乌拉特后旗| 乌兰浩特市| 日喀则市| 镇巴县| 淮安市| 灌云县| 丰原市| 奉节县| 全南县| 青河县| 武宁县| 察哈| 郯城县| 清镇市| 敖汉旗| 沭阳县| 荣昌县| 蓝田县| 山丹县| 磐安县| 通城县| 桃源县| 宁阳县| 黑山县| 新乡市| 荥阳市| 富阳市| 油尖旺区| 刚察县| 双柏县| 商丘市| 娄烦县| 噶尔县| 宜昌市| 陵水| 余干县| 沈阳市| 茂名市| 常山县| 鹤庆县| 廊坊市|