stack.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { computed, shallowReactive, isRef, watch } from "vue";
  2. import type { ComputedRef, UnwrapRef } from "vue";
  3. export type Stack<T> = {
  4. push: (raw: T) => () => void;
  5. pop: () => T;
  6. length: ComputedRef<number>;
  7. current: ComputedRef<T>;
  8. };
  9. // 栈构建
  10. export const stackFactory = <T>(initVal?: T, debug?: boolean): Stack<T> => {
  11. const stack = shallowReactive([]) as Array<T>;
  12. if (initVal !== void 0) {
  13. stack.push(initVal);
  14. }
  15. return {
  16. push(raw: T) {
  17. stack.push(raw);
  18. if (debug) {
  19. console.warn('push', raw)
  20. }
  21. return () => {
  22. const index = stack.indexOf(raw);
  23. ~index && stack.splice(index, 1);
  24. if (debug) {
  25. console.warn('pop', raw)
  26. console.warn('current', stack)
  27. }
  28. };
  29. },
  30. pop() {
  31. let ret = stack[stack.length-- - 1];
  32. if (debug) {
  33. console.warn('pop current', stack)
  34. }
  35. return ret;
  36. },
  37. current: computed(() => {
  38. return stack[stack.length - 1];
  39. }),
  40. length: computed(() => stack.length),
  41. };
  42. };
  43. export const flatStacksValue = <T extends { [key in any]: Stack<any> }>(
  44. stacks: T
  45. ) => {
  46. const result = {} as {
  47. [key in keyof T]: UnwrapRef<T[key]["current"]["value"]>;
  48. };
  49. const keys = Object.keys(stacks) as Array<keyof T>;
  50. const proxy = new Proxy(result, {
  51. get(_, key: keyof T) {
  52. if (keys.includes(key)) {
  53. return isRef(stacks[key].current.value)
  54. ? (stacks[key].current.value as any).value
  55. : stacks[key].current.value;
  56. } else {
  57. return stacks[key];
  58. }
  59. },
  60. set(_, key: keyof T, val) {
  61. if (isRef(stacks[key].current.value)) {
  62. (stacks[key].current.value as any).value = val;
  63. } else {
  64. (stacks[key].current.value as any) = val;
  65. }
  66. return true;
  67. },
  68. });
  69. return proxy;
  70. };