Browse Source

feat(组件): 增加SmartPageProvider组件,通过inject provide支持字典批量加载

shizhongming 2 years ago
parent
commit
262c1dd2cb

+ 3 - 74
src/components/Form/src/smart-boot/components/SmartApiSelectDict.vue

@@ -1,24 +1,5 @@
 <template>
-  <Select
-    v-if="computedHasProvider"
-    v-bind="$attrs"
-    :options="computedOptions"
-    v-model:value="state"
-    @change="handleChange"
-  >
-    <template #[item]="data" v-for="item in Object.keys($slots)">
-      <slot :name="item" v-bind="data || {}"></slot>
-    </template>
-    <template #suffixIcon v-if="loadingRef">
-      <LoadingOutlined spin />
-    </template>
-    <template #notFoundContent v-if="loadingRef">
-      <span>
-        <LoadingOutlined spin class="mr-1" />
-        {{ t('component.form.apiSelectNotFound') }}
-      </span>
-    </template>
-  </Select>
+  <SmartApiDictProviderSelect v-if="computedHasProvider" v-bind="$attrs" :dict-code="dictCode" />
   <ApiSelect
     v-else
     v-bind="$attrs"
@@ -29,39 +10,19 @@
 </template>
 
 <script lang="ts" setup>
-  import { type PropType, ref, Ref, watch } from 'vue';
-  import type { SelectValue } from 'ant-design-vue/es/select';
-
   import { computed, inject } from 'vue';
-  import { Select } from 'ant-design-vue';
   import ApiSelect from '../../components/ApiSelect.vue';
   import { propTypes } from '@/utils/propTypes';
   import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
   import { SmartProviderConstants } from '@/components/SmartPageProvider';
-  import { LoadingOutlined } from '@ant-design/icons-vue';
-  import { useRuleFormItem } from '@/hooks/component/useFormItem';
-  import { useI18n } from '@/hooks/web/useI18n';
-
-  type OptionsItem = { label?: string; value?: string; disabled?: boolean; [name: string]: any };
+  import SmartApiDictProviderSelect from './provider/SmartApiDictProviderSelect.vue';
 
   const props = defineProps({
     dictCode: propTypes.string.isRequired,
-    value: { type: [Array, Object, String, Number] as PropType<SelectValue> },
-    numberToString: propTypes.bool,
   });
 
-  const emit = defineEmits(['change', 'update:value']);
-
-  const { t } = useI18n();
+  const registerHandler = inject(SmartProviderConstants.dictRegisterIdent, null) as boolean | null;
 
-  const registerHandler = inject(SmartProviderConstants.dictRegisterKey, null) as Function | null;
-  if (registerHandler) {
-    registerHandler(props.dictCode);
-  }
-  /**
-   * 加载状态
-   */
-  const loadingRef = inject(SmartProviderConstants.dictLoadingKey, null) as Ref<boolean> | null;
   /**
    * 是否有注入
    */
@@ -69,38 +30,6 @@
     return registerHandler !== null;
   });
 
-  /**
-   * 注入OPTIONS
-   */
-  const dictDataRef = inject(SmartProviderConstants.dictData, null) as Map<
-    string,
-    Recordable[]
-  > | null;
-  const computedOptions = computed(() => {
-    if (!dictDataRef) {
-      return [];
-    }
-    const dictData = dictDataRef.get(props.dictCode);
-    if (!dictData) {
-      return [];
-    }
-    return dictData;
-  });
-
-  const emitData = ref<OptionsItem[]>([]);
-  const [state] = useRuleFormItem(props, 'value', 'change', emitData);
-
-  watch(
-    () => state.value,
-    (v) => {
-      emit('update:value', v);
-    },
-  );
-
-  function handleChange(_, ...args) {
-    emitData.value = args;
-  }
-
   const api = () => {
     return defHttp.post({
       service: ApiServiceEnum.SMART_SYSTEM,

+ 82 - 0
src/components/Form/src/smart-boot/components/provider/SmartApiDictProviderSelect.vue

@@ -0,0 +1,82 @@
+<template>
+  <Select v-bind="$attrs" :options="computedOptions" v-model:value="state" @change="handleChange">
+    <template #[item]="data" v-for="item in Object.keys($slots)">
+      <slot :name="item" v-bind="data || {}"></slot>
+    </template>
+    <template #suffixIcon v-if="loadingRef">
+      <LoadingOutlined spin />
+    </template>
+    <template #notFoundContent v-if="loadingRef">
+      <span>
+        <LoadingOutlined spin class="mr-1" />
+        {{ t('component.form.apiSelectNotFound') }}
+      </span>
+    </template>
+  </Select>
+</template>
+
+<script setup lang="ts">
+  import { type Ref, inject, type PropType, computed, watch, ref } from 'vue';
+
+  import { Select } from 'ant-design-vue';
+  import { LoadingOutlined } from '@ant-design/icons-vue';
+  import { SmartProviderConstants } from '@/components/SmartPageProvider';
+  import { useI18n } from '@/hooks/web/useI18n';
+  import { propTypes } from '@/utils/propTypes';
+  import type { SelectValue } from 'ant-design-vue/es/select';
+  import { useRuleFormItem } from '@/hooks/component/useFormItem';
+
+  type OptionsItem = { label?: string; value?: string; disabled?: boolean; [name: string]: any };
+
+  const props = defineProps({
+    dictCode: propTypes.string.isRequired,
+    value: { type: [Array, Object, String, Number] as PropType<SelectValue> },
+    numberToString: propTypes.bool,
+  });
+
+  const emit = defineEmits(['change', 'update:value']);
+
+  const { t } = useI18n();
+  /**
+   * 加载状态
+   */
+  const loadingRef = inject(SmartProviderConstants.dictLoadingKey, null) as Ref<boolean> | null;
+
+  const registerHandler = inject(SmartProviderConstants.dictRegisterKey, null) as Function | null;
+  if (registerHandler) {
+    registerHandler(props.dictCode);
+  }
+
+  const emitData = ref<OptionsItem[]>([]);
+  const [state] = useRuleFormItem(props, 'value', 'change', emitData);
+  watch(
+    () => state.value,
+    (v) => {
+      emit('update:value', v);
+    },
+  );
+
+  function handleChange(_, ...args) {
+    emitData.value = args;
+  }
+
+  /**
+   * 注入OPTIONS
+   */
+  const dictDataRef = inject(SmartProviderConstants.dictData, null) as Map<
+    string,
+    Recordable[]
+  > | null;
+  const computedOptions = computed(() => {
+    if (!dictDataRef) {
+      return [];
+    }
+    const dictData = dictDataRef.get(props.dictCode);
+    if (!dictData) {
+      return [];
+    }
+    return dictData;
+  });
+</script>
+
+<style scoped lang="less"></style>

+ 1 - 0
src/components/SmartPageProvider/src/constants.ts

@@ -1,4 +1,5 @@
 export const SmartProviderConstants = {
+  dictRegisterIdent: Symbol('smart_provider_dict_select_register_ident'),
   dictRegisterKey: Symbol('smart_provider_dict_select_register'),
   dictLoadingKey: Symbol('SMART_PROVIDER_DICT_SELECT_LOADING'),
   dictData: Symbol('SMART_PROVIDER_DICT_SELECT_DATA'),

+ 2 - 0
src/components/SmartPageProvider/src/hooks/useProviderDict.ts

@@ -86,4 +86,6 @@ export const useProviderDict = () => {
   provide(SmartProviderConstants.dictData, dictDataMap);
 
   provide(SmartProviderConstants.dictMap, computedDictMap);
+
+  provide(SmartProviderConstants.dictRegisterIdent, true);
 };