block.vue 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. <template>
  2. <div class="block">
  3. <h5 class="title">{{ title }}</h5>
  4. <div v-for="option in options" :key="option.name" class="switch-wrapper">
  5. <span>{{ $t(option.name) }}</span>
  6. <form-wrapper
  7. :type="option.type || 'switch'"
  8. :name="option.key"
  9. :default-value="option.defaultVal"
  10. @input-change="handleChange"
  11. />
  12. </div>
  13. </div>
  14. </template>
  15. <script lang="ts" setup>
  16. import { PropType } from 'vue';
  17. import { useAppStore } from '@/store';
  18. import FormWrapper from './form-wrapper.vue';
  19. interface OptionsProps {
  20. name: string;
  21. key: string;
  22. type?: string;
  23. defaultVal?: boolean | string | number;
  24. }
  25. defineProps({
  26. title: {
  27. type: String,
  28. default: '',
  29. },
  30. options: {
  31. type: Array as PropType<OptionsProps[]>,
  32. default() {
  33. return [];
  34. },
  35. },
  36. });
  37. const appStore = useAppStore();
  38. const handleChange = async ({
  39. key,
  40. value,
  41. }: {
  42. key: string;
  43. value: unknown;
  44. }) => {
  45. if (key === 'colorWeak') {
  46. document.body.style.filter = value ? 'invert(80%)' : 'none';
  47. }
  48. if (key === 'menuFromServer' && value) {
  49. await appStore.fetchServerMenuConfig();
  50. }
  51. if (key === 'topMenu') {
  52. appStore.updateSettings({
  53. menuCollapse: false,
  54. });
  55. }
  56. appStore.updateSettings({ [key]: value });
  57. };
  58. </script>
  59. <style scoped lang="less">
  60. .block {
  61. margin-bottom: 24px;
  62. }
  63. .title {
  64. margin: 10px 0;
  65. padding: 0;
  66. font-size: 14px;
  67. }
  68. .switch-wrapper {
  69. display: flex;
  70. align-items: center;
  71. justify-content: space-between;
  72. height: 32px;
  73. }
  74. </style>