车间能级提升-智能设备管理系统
朱桂飞
2025-01-09 3e8f7f239bedae0b4f04a1ac6bd443ba6298f73c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import type { ExtendedModalApi, ModalApiOptions, ModalProps } from './modal';
 
import { defineComponent, h, inject, nextTick, provide, reactive } from 'vue';
 
import { useStore } from '@vben-core/shared/store';
 
import VbenModal from './modal.vue';
import { ModalApi } from './modal-api';
 
const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT');
 
export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
  options: ModalApiOptions = {},
) {
  // Modal一般会抽离出来,所以如果有传入 connectedComponent,则表示为外部调用,与内部组件进行连接
  // 外部的Modal通过provide/inject传递api
 
  const { connectedComponent } = options;
  if (connectedComponent) {
    const extendedApi = reactive({});
    const Modal = defineComponent(
      (props: TParentModalProps, { attrs, slots }) => {
        provide(USER_MODAL_INJECT_KEY, {
          extendApi(api: ExtendedModalApi) {
            // 不能直接给 reactive 赋值,会丢失响应
            // 不能用 Object.assign,会丢失 api 的原型函数
            Object.setPrototypeOf(extendedApi, api);
          },
          options,
        });
        checkProps(extendedApi as ExtendedModalApi, {
          ...props,
          ...attrs,
          ...slots,
        });
        return () =>
          h(
            connectedComponent,
            {
              ...props,
              ...attrs,
            },
            slots,
          );
      },
      {
        inheritAttrs: false,
        name: 'VbenParentModal',
      },
    );
    return [Modal, extendedApi as ExtendedModalApi] as const;
  }
 
  const injectData = inject<any>(USER_MODAL_INJECT_KEY, {});
 
  const mergedOptions = {
    ...injectData.options,
    ...options,
  } as ModalApiOptions;
 
  mergedOptions.onOpenChange = (isOpen: boolean) => {
    options.onOpenChange?.(isOpen);
    injectData.options?.onOpenChange?.(isOpen);
  };
  const api = new ModalApi(mergedOptions);
 
  const extendedApi: ExtendedModalApi = api as never;
 
  extendedApi.useStore = (selector) => {
    return useStore(api.store, selector);
  };
 
  const Modal = defineComponent(
    (props: ModalProps, { attrs, slots }) => {
      return () =>
        h(
          VbenModal,
          {
            ...props,
            ...attrs,
            modalApi: extendedApi,
          },
          slots,
        );
    },
    {
      inheritAttrs: false,
      name: 'VbenModal',
    },
  );
  injectData.extendApi?.(extendedApi);
  return [Modal, extendedApi] as const;
}
 
async function checkProps(api: ExtendedModalApi, attrs: Record<string, any>) {
  if (!attrs || Object.keys(attrs).length === 0) {
    return;
  }
  await nextTick();
 
  const state = api?.store?.state;
 
  if (!state) {
    return;
  }
 
  const stateKeys = new Set(Object.keys(state));
 
  for (const attr of Object.keys(attrs)) {
    if (stateKeys.has(attr) && !['class'].includes(attr)) {
      // connectedComponent存在时,不要传入Modal的props,会造成复杂度提升,如果你需要修改Modal的props,请使用 useModal 或者api
      console.warn(
        `[Vben Modal]: When 'connectedComponent' exists, do not set props or slots '${attr}', which will increase complexity. If you need to modify the props of Modal, please use useVbenModal or api.`,
      );
    }
  }
}