当前位置:   article > 正文

二次封装前端本地存储localStorage与sessionStorage_ts js 使用 local storage

ts js 使用 local storage

使用typescript进行了二次封装,"typescript": "5.2.2"。下有编译好的js代码。


目录

应用场景

一、ts代码

二、编译js

1.代码

 2.使用方式

总结

应用场景

        同源下多个应用进行存储隔离

一、ts代码

  1. "use strict";
  2. // @ts-check
  3. /**
  4. * @description: 装饰器:检查函数入参类型
  5. * @param {string | string[]} type 基本数据类型 || 基本数据类型集合
  6. */
  7. function checkType(type: string | string[]) {
  8. return function (value: Function, { kind, name }) {
  9. return function (...args: any[]) {
  10. if (Array.isArray(type)) {
  11. args.forEach((item, index) => {
  12. if (typeof item !== type[index]) {
  13. throw new Error(`${kind}: ${name} params[${index}] is not ${type[index]}`);
  14. }
  15. })
  16. } else {
  17. args.forEach((item, index) => {
  18. if (typeof item !== type) {
  19. throw new Error(`${kind}: ${name} params[${index}] is not ${type}`);
  20. }
  21. })
  22. }
  23. return value.call(this, ...args);
  24. };
  25. }
  26. }
  27. /**
  28. * @description: 装饰器:限制参数长度
  29. * @param {number} extent 必传参数长度
  30. */
  31. function limit(extent: number) {
  32. return function (value: Function, { kind, name }) {
  33. return function (...args: any[]) {
  34. if (args.length < extent) {
  35. throw new Error(`${kind}: ${name} Expect ${extent} parameters, actual ${args.length}`);
  36. }
  37. return value.call(this, ...args);
  38. };
  39. }
  40. }
  41. abstract class Base {
  42. public original: Storage;
  43. protected prefix: string;
  44. constructor(original: Storage, prefix: string) {
  45. this.original = original;
  46. this.prefix = prefix;
  47. }
  48. protected getKey(key: string): string {
  49. return `${this.prefix}_${key}`;
  50. }
  51. }
  52. class WebStorage extends Base {
  53. constructor(original: Storage, prefix: string) {
  54. super(original, prefix);
  55. }
  56. @limit(1)
  57. @checkType("string")
  58. public getItem(key: string): string | null {
  59. const data = this.original.getItem(this.getKey(key));
  60. if (data === null) return null;
  61. try {
  62. const { value, indate } = JSON.parse(data);
  63. if (indate === null) return value;
  64. if (indate >= Date.now()) {
  65. return value;
  66. } else {
  67. this.removeItem(key);
  68. return null;
  69. }
  70. } catch (error) {
  71. return data;
  72. }
  73. }
  74. /**
  75. * @description: 调用存储
  76. * @param {string} key 键
  77. * @param {string} value 值
  78. * @param {timestamp} indate 时间戳-键值有效时间
  79. */
  80. @limit(2)
  81. @checkType(["string", "string", "number"])
  82. public setItem(key: string, value: string, indate?: number): void {
  83. this.original.setItem(
  84. this.getKey(key),
  85. JSON.stringify({
  86. value: value,
  87. indate: indate ? Date.now() + indate : null
  88. })
  89. );
  90. }
  91. @limit(1)
  92. @checkType("string")
  93. public removeItem(key: string): void {
  94. this.original.removeItem(this.getKey(key));
  95. }
  96. public clear(): void {
  97. this.original.clear();
  98. }
  99. }
  100. export default WebStorage;

代码不过多解释,不复杂,还有注释。 

使用了新版ts装饰器,这也是我第一次尝试,据说性能更棒。

二、编译js

1.代码

  1. "use strict";
  2. var __extends = (this && this.__extends) || (function () {
  3. var extendStatics = function (d, b) {
  4. extendStatics = Object.setPrototypeOf ||
  5. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  6. function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
  7. return extendStatics(d, b);
  8. };
  9. return function (d, b) {
  10. if (typeof b !== "function" && b !== null)
  11. throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
  12. extendStatics(d, b);
  13. function __() { this.constructor = d; }
  14. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  15. };
  16. })();
  17. var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
  18. var useValue = arguments.length > 2;
  19. for (var i = 0; i < initializers.length; i++) {
  20. value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
  21. }
  22. return useValue ? value : void 0;
  23. };
  24. var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
  25. function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
  26. var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
  27. var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
  28. var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
  29. var _, done = false;
  30. for (var i = decorators.length - 1; i >= 0; i--) {
  31. var context = {};
  32. for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
  33. for (var p in contextIn.access) context.access[p] = contextIn.access[p];
  34. context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
  35. var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
  36. if (kind === "accessor") {
  37. if (result === void 0) continue;
  38. if (result === null || typeof result !== "object") throw new TypeError("Object expected");
  39. if (_ = accept(result.get)) descriptor.get = _;
  40. if (_ = accept(result.set)) descriptor.set = _;
  41. if (_ = accept(result.init)) initializers.unshift(_);
  42. }
  43. else if (_ = accept(result)) {
  44. if (kind === "field") initializers.unshift(_);
  45. else descriptor[key] = _;
  46. }
  47. }
  48. if (target) Object.defineProperty(target, contextIn.name, descriptor);
  49. done = true;
  50. };
  51. var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
  52. if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
  53. if (ar || !(i in from)) {
  54. if (!ar) ar = Array.prototype.slice.call(from, 0, i);
  55. ar[i] = from[i];
  56. }
  57. }
  58. return to.concat(ar || Array.prototype.slice.call(from));
  59. };
  60. Object.defineProperty(exports, "__esModule", { value: true });
  61. // @ts-check
  62. /**
  63. * @description: 装饰器:检查函数入参类型
  64. * @param {string | string[]} type 基本数据类型 || 基本数据类型集合
  65. */
  66. function checkType(type) {
  67. return function (value, _a) {
  68. var kind = _a.kind, name = _a.name;
  69. return function () {
  70. var args = [];
  71. for (var _i = 0; _i < arguments.length; _i++) {
  72. args[_i] = arguments[_i];
  73. }
  74. if (Array.isArray(type)) {
  75. args.forEach(function (item, index) {
  76. if (typeof item !== type[index]) {
  77. throw new Error("".concat(kind, ": ").concat(name, " params[").concat(index, "] is not ").concat(type[index]));
  78. }
  79. });
  80. }
  81. else {
  82. args.forEach(function (item, index) {
  83. if (typeof item !== type) {
  84. throw new Error("".concat(kind, ": ").concat(name, " params[").concat(index, "] is not ").concat(type));
  85. }
  86. });
  87. }
  88. return value.call.apply(value, __spreadArray([this], args, false));
  89. };
  90. };
  91. }
  92. /**
  93. * @description: 装饰器:限制参数长度
  94. * @param {number} extent 必传参数长度
  95. */
  96. function limit(extent) {
  97. return function (value, _a) {
  98. var kind = _a.kind, name = _a.name;
  99. return function () {
  100. var args = [];
  101. for (var _i = 0; _i < arguments.length; _i++) {
  102. args[_i] = arguments[_i];
  103. }
  104. if (args.length < extent) {
  105. throw new Error("".concat(kind, ": ").concat(name, " Expect ").concat(extent, " parameters, actual ").concat(args.length));
  106. }
  107. return value.call.apply(value, __spreadArray([this], args, false));
  108. };
  109. };
  110. }
  111. var Base = /** @class */ (function () {
  112. function Base(original, prefix) {
  113. this.original = original;
  114. this.prefix = prefix;
  115. }
  116. Base.prototype.getKey = function (key) {
  117. return "".concat(this.prefix, "_").concat(key);
  118. };
  119. return Base;
  120. }());
  121. var WebStorage = function () {
  122. var _a;
  123. var _classSuper = Base;
  124. var _instanceExtraInitializers = [];
  125. var _getItem_decorators;
  126. var _setItem_decorators;
  127. var _removeItem_decorators;
  128. return _a = /** @class */ (function (_super) {
  129. __extends(WebStorage, _super);
  130. function WebStorage(original, prefix) {
  131. var _this = _super.call(this, original, prefix) || this;
  132. __runInitializers(_this, _instanceExtraInitializers);
  133. return _this;
  134. }
  135. WebStorage.prototype.getItem = function (key) {
  136. var data = this.original.getItem(this.getKey(key));
  137. if (data === null)
  138. return null;
  139. try {
  140. var _b = JSON.parse(data), value = _b.value, indate = _b.indate;
  141. if (indate === null)
  142. return value;
  143. if (indate >= Date.now()) {
  144. return value;
  145. }
  146. else {
  147. this.removeItem(key);
  148. return null;
  149. }
  150. }
  151. catch (error) {
  152. return data;
  153. }
  154. };
  155. /**
  156. * @description: 调用存储
  157. * @param {string} key 键
  158. * @param {string} value 值
  159. * @param {timestamp} indate 时间戳-键值有效时间
  160. */
  161. WebStorage.prototype.setItem = function (key, value, indate) {
  162. this.original.setItem(this.getKey(key), JSON.stringify({
  163. value: value,
  164. indate: indate ? Date.now() + indate : null
  165. }));
  166. };
  167. WebStorage.prototype.removeItem = function (key) {
  168. this.original.removeItem(this.getKey(key));
  169. };
  170. WebStorage.prototype.clear = function () {
  171. this.original.clear();
  172. };
  173. return WebStorage;
  174. }(_classSuper)),
  175. (function () {
  176. var _b;
  177. var _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_b = _classSuper[Symbol.metadata]) !== null && _b !== void 0 ? _b : null) : void 0;
  178. _getItem_decorators = [limit(1), checkType("string")];
  179. _setItem_decorators = [limit(2), checkType(["string", "string", "number"])];
  180. _removeItem_decorators = [limit(1), checkType("string")];
  181. __esDecorate(_a, null, _getItem_decorators, { kind: "method", name: "getItem", static: false, private: false, access: { has: function (obj) { return "getItem" in obj; }, get: function (obj) { return obj.getItem; } }, metadata: _metadata }, null, _instanceExtraInitializers);
  182. __esDecorate(_a, null, _setItem_decorators, { kind: "method", name: "setItem", static: false, private: false, access: { has: function (obj) { return "setItem" in obj; }, get: function (obj) { return obj.setItem; } }, metadata: _metadata }, null, _instanceExtraInitializers);
  183. __esDecorate(_a, null, _removeItem_decorators, { kind: "method", name: "removeItem", static: false, private: false, access: { has: function (obj) { return "removeItem" in obj; }, get: function (obj) { return obj.removeItem; } }, metadata: _metadata }, null, _instanceExtraInitializers);
  184. if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
  185. })(),
  186. _a;
  187. }();
  188. exports.default = WebStorage;

 2.使用方式

  1. import WebStorage from "./webStorage.js";
  2. const prefix = "projectName";
  3. const customStorage = {
  4. localStorage: new WebStorage(window.localStorage, prefix),
  5. sessionStorage: new WebStorage(window.sessionStorage, prefix)
  6. };
  7. customStorage.localStorage.setItem("test1", "a");
  8. console.log(customStorage.localStorage.getItem("test1"));
  9. customStorage.localStorage.setItem("test2", "b", 3000);
  10. console.log(customStorage.localStorage.getItem("test2"));
  11. setTimeout(() => {
  12. console.log(customStorage.localStorage.getItem("test2"))
  13. }, 5000);

基本对标原生态的使用方式,传参类型更严格,新增了存储过期的能力,使用无过多心智开销。 项目支持ts就用ts,仅支持js就用编译好的js,一样滴。使用方式建议挂载在一个公共的对象上,进行向下分发,不进行多次初始化。 


总结

觉得写的有问题的地方可以自己修改ts代码,重新使用typescript编译成js,欢迎大佬们评论区指点错误。如果有更好应对该场景的解决方案,留下链接让我学习一下。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/482291
推荐阅读
相关标签