preferences.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <script lang="ts" setup>
  2. import { computed } from 'vue';
  3. import { Settings } from '@vben/icons';
  4. import { $t, loadLocaleMessages } from '@vben/locales';
  5. import { preferences, updatePreferences } from '@vben/preferences';
  6. import { capitalizeFirstLetter } from '@vben/utils';
  7. import { useVbenDrawer } from '@vben-core/popup-ui';
  8. import { VbenButton } from '@vben-core/shadcn-ui';
  9. import PreferencesDrawer from './preferences-drawer.vue';
  10. interface Props {
  11. /** 是否显示按钮 */
  12. showButton?: boolean;
  13. }
  14. const props = withDefaults(defineProps<Props>(), {
  15. showButton: true,
  16. });
  17. const emit = defineEmits<{ clearPreferencesAndLogout: [] }>();
  18. const [Drawer, drawerApi] = useVbenDrawer({
  19. connectedComponent: PreferencesDrawer,
  20. });
  21. // 暴露打开抽屉的方法
  22. defineExpose({
  23. open: () => drawerApi.open(),
  24. });
  25. /**
  26. * preferences 转成 vue props
  27. * preferences.widget.fullscreen=>widgetFullscreen
  28. */
  29. const attrs = computed(() => {
  30. const result: Record<string, any> = {};
  31. for (const [key, value] of Object.entries(preferences)) {
  32. for (const [subKey, subValue] of Object.entries(value)) {
  33. result[`${key}${capitalizeFirstLetter(subKey)}`] = subValue;
  34. }
  35. }
  36. return result;
  37. });
  38. /**
  39. * preferences 转成 vue listener
  40. * preferences.widget.fullscreen=>@update:widgetFullscreen
  41. */
  42. const listen = computed(() => {
  43. const result: Record<string, any> = {};
  44. for (const [key, value] of Object.entries(preferences)) {
  45. if (typeof value === 'object') {
  46. for (const subKey of Object.keys(value)) {
  47. result[`update:${key}${capitalizeFirstLetter(subKey)}`] = (
  48. val: any,
  49. ) => {
  50. updatePreferences({ [key]: { [subKey]: val } });
  51. if (key === 'app' && subKey === 'locale') {
  52. loadLocaleMessages(val);
  53. }
  54. };
  55. }
  56. } else {
  57. result[key] = value;
  58. }
  59. }
  60. return result;
  61. });
  62. </script>
  63. <template>
  64. <div>
  65. <Drawer
  66. v-bind="{ ...$attrs, ...attrs }"
  67. v-on="listen"
  68. @clear-preferences-and-logout="emit('clearPreferencesAndLogout')"
  69. />
  70. <!-- 触发打开抽屉的按钮(可覆盖) -->
  71. <slot>
  72. <VbenButton
  73. v-if="props.showButton"
  74. :title="$t('preferences.title')"
  75. class="flex-col-center size-10 cursor-pointer rounded-l-lg rounded-r-none border-none bg-primary"
  76. @click="() => drawerApi.open()"
  77. >
  78. <Settings class="size-5" />
  79. </VbenButton>
  80. </slot>
  81. </div>
  82. </template>