refs.ts 2.6 KB

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