天天看點

我從Vue3 中學到的 7 個超級實用的開發技巧

我從Vue3 中學到的 7 個超級實用的開發技巧

在本文中,我将與您分享7個我在 Vue3 中學習到的一些實用功能小技巧,我把源碼放在這裡。這些函數具有高度的可重用性,對日常開發很有用,是以,讓我們開始吧!

1、判斷一個字元串是否以on開頭

const onRE = /^on[^a-z]/;
const isOn = (key: string) => onRE.test(key);
console.log(isOn('onClick')); // true
console.log(isOn('onclick')); // false      

我們可以看到它使用了正則比對。它将比對以 on 開頭且下一個字元不是 a 到 z 的字母。

2、确定property是否為自己的

const hasOwnProperty = Object.prototype.hasOwnProperty;
const hasOwn = (val: object, key: string | symbol): key is keyof typeof val =>
  hasOwnProperty.call(val, key);
const testObj = { name: 1 };
console.log(hasOwn(testObj, 'name')); // true
Object.getPrototypeOf(testObj).age = 2;
console.log(hasOwn(testObj, 'age')); // false      

此方法使用 Object.prototype.hasOwnProperty 來确定鍵是否是對象本身的屬性。

當我們使用 Object.getPrototypeOf() 擷取 testObj 的原型并在其上設定 age 屬性時,hasOwn 将傳回 false。

除此之外,它在這裡使用 TypeScript 的 is 關鍵字,它建立了一個使用者定義的類型保護,在運作時檢查以確定它是我們在特定範圍内期望的類型。

3、判斷是否為Promise

const isObject = (val: unknown): val is Record<any, any> =>
  val !== null && typeof val === 'object';
const isFunction = (val: unknown): val is Function => typeof val === 'function';
const isPromise = <T = any>(val: unknown): val is Promise<T> => {
  return isObject(val) && isFunction(val.then) &&      isFunction(val.catch);
};
console.log(isPromise(new Promise(() => {}))); // true
console.log(isPromise(async function () {})); // false
console.log(isPromise(function* () {})); // false      

此方法借用isObject判斷目前值對象,借用isFunction判斷目前值的then和catch屬性是函數。

他們三個也都使用 is 關鍵字。此外,isPromise 還使用泛型來傳遞 Promise 的 Result 類型。

4、判斷是否為整數字元串

const isString = (val: unknown): val is string => typeof val === 'string';
const isIntegerKey = (key: unknown) =>
  isString(key) &&
  key !== 'NaN' &&
  key[0] !== '-' &&
  '' + parseInt(key, 10) === key;
console.log(isIntegerKey('10')); // true
console.log(isIntegerKey('010')); // false
console.log(isIntegerKey('3.0')); // false
console.log(isIntegerKey('Vue')); // false      

先用isString判斷是否為字元串類型,再判斷是否為'NaN'且首字元不是-,最後用空字元串将parseInt轉換後的十進制數轉為字元串,判斷是否為等于原始字元串。

5、緩存字元串計算結果

const cacheStringFunction = <T extends (str: string) => string>(fn: T): T => {
  const cache: Record<string, string> = Object.create(null);
  return ((str: string) => {
    const hit = cache[str];
    return hit || (cache[str] = fn(str));
  }) as any;
};
const getUpperCase = cacheStringFunction((str: string): string =>
  str.toUpperCase(),
);
console.log(getUpperCase('a')); // A
console.log(getUpperCase('a')); // A      

這是一個高階函數,内部使用閉包來緩存之前的計算結果,如果再次調用時發現已經計算過,則傳回之前的結果。

6、連字元轉駝峰/駝峰轉連字元

const cacheStringFunction = <T extends (str: string) => string>(fn: T): T => {
  const cache: Record<string, string> = Object.create(null);
  return ((str: string) => {
    const hit = cache[str];
    return hit || (cache[str] = fn(str));
  }) as any;
};
const camelizeRE = /-(\w)/g;
const camelize = cacheStringFunction((str: string): string => {
  return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
});
const hyphenateRE = /\B([A-Z])/g;
const hyphenate = cacheStringFunction((str: string) =>
  str.replace(hyphenateRE, '-$1').toLowerCase(),
);
console.log(camelize('on-click')); // onClick
console.log(camelize('test-a-click')); // testAClick
console.log(hyphenate('onClick')); // on-click
console.log(hyphenate('testAClick')); // test-a-click      

以上兩種方法都使用正規表達式比對和使用String.prototype.replace()替換字元,并且都被上一節介紹的緩存函數包裹,也就是說一旦需要處理相同的字元串, 會直接傳回緩存結果。

7、擷取目前環境的全局對象

let _globalThis: any;
const getGlobalThis = (): any => {
  return (
    _globalThis ||
    (_globalThis =
      typeof globalThis !== 'undefined'
        ? globalThis
        : typeof self !== 'undefined'
        ? self
        : typeof window !== 'undefined'
        ? window
        : typeof global !== 'undefined'
        ? global
        : {})
  );
};
console.log(getGlobalThis());
console.log(getGlobalThis());      

這裡也用到了閉包,但是,這次閉包存儲的 _globalThis 是在目前加載的子產品中,是以,隻需要調用一次,判斷一次,不需要後續的判斷。

我們看一下函數内部的邏輯,它的優先級是:

  1. 使用 globalThis,它提供了一種跨環境通路全局對象的标準方法。
  2. 判斷self,這是因為在Web Workers中,無法通路window對象,隻能通過self通路目前全局對象。
  3. 常見的視窗對象。
  4. Node.js 中的全局對象。

總結

今天内容就到這裡了,希望對你有所幫助,感謝你的閱讀,祝程式設計愉快!

學習更多技能

請點選下方公衆号