refs.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import { reactive } from "vue";
  2. import { isNull } from "../utils";
  3. // #ifdef APP
  4. // @ts-ignore
  5. type Instance = ComponentPublicInstance | null;
  6. // #endif
  7. // #ifndef APP
  8. // @ts-ignore
  9. type Instance = any;
  10. // #endif
  11. /**
  12. * Refs 类用于管理组件引用,便于在组合式 API 中获取、操作子组件实例。
  13. */
  14. class Refs {
  15. // 存储所有 ref 的响应式对象,key 为 ref 名称,value 为组件实例
  16. data = reactive({} as UTSJSONObject);
  17. /**
  18. * 生成 ref 绑定函数,用于在模板中设置 ref。
  19. * @param name ref 名称
  20. * @returns 绑定函数 (el: Instance) => void
  21. */
  22. set(name: string) {
  23. return (el: Instance) => {
  24. this.data[name] = el;
  25. };
  26. }
  27. /**
  28. * 获取指定名称的组件实例
  29. * @param name ref 名称
  30. * @returns 组件实例或 null
  31. */
  32. get(name: string): Instance {
  33. const d = this.data[name] as ComponentPublicInstance;
  34. if (isNull(d)) {
  35. return null;
  36. }
  37. return d;
  38. }
  39. /**
  40. * 获取组件实例暴露的属性或方法(兼容不同平台)
  41. * @param name ref 名称
  42. * @param key 暴露的属性名
  43. * @returns 属性值或 null
  44. */
  45. getExposed<T>(name: string, key: string): T | null {
  46. // #ifdef APP-ANDROID
  47. const d = this.get(name);
  48. if (isNull(d)) {
  49. return null;
  50. }
  51. // 安卓平台下,$exposed 为 Map<string, any>
  52. const ex = d!.$exposed as Map<string, any>;
  53. if (isNull(ex)) {
  54. return null;
  55. }
  56. return ex[key] as T | null;
  57. // #endif
  58. // #ifndef APP-ANDROID
  59. // 其他平台直接通过属性访问
  60. return this.get(name)?.[key] as T;
  61. // #endif
  62. }
  63. /**
  64. * 调用组件实例暴露的方法,并返回结果
  65. * @param name ref 名称
  66. * @param method 方法名
  67. * @param data 传递的数据
  68. * @returns 方法返回值
  69. */
  70. call<T>(name: string, method: string, data: UTSJSONObject | null = null): T {
  71. return this.get(name)!.$callMethod(method, data) as T;
  72. }
  73. /**
  74. * 调用组件实例暴露的方法,无返回值
  75. * @param name ref 名称
  76. * @param method 方法名
  77. * @param data 传递的数据
  78. */
  79. callMethod(name: string, method: string, data: UTSJSONObject | null = null): void {
  80. this.get(name)!.$callMethod(method, data);
  81. }
  82. /**
  83. * 调用组件的 open 方法,常用于弹窗、抽屉等组件
  84. * @param name ref 名称
  85. * @param data 传递的数据
  86. */
  87. open(name: string, data: UTSJSONObject | null = null) {
  88. this.callMethod(name, "open", data);
  89. }
  90. /**
  91. * 调用组件的 close 方法,常用于弹窗、抽屉等组件
  92. * @param name ref 名称
  93. */
  94. close(name: string) {
  95. return this.callMethod(name, "close");
  96. }
  97. }
  98. /**
  99. * useRefs 组合式函数,返回 Refs 实例
  100. * @returns Refs 实例
  101. */
  102. export function useRefs(): Refs {
  103. return new Refs();
  104. }