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">
  16. import { defineComponent, 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. export default defineComponent({
  26. components: {
  27. FormWrapper,
  28. },
  29. props: {
  30. title: {
  31. type: String,
  32. default: '',
  33. },
  34. options: {
  35. type: Array as PropType<OptionsProps[]>,
  36. default() {
  37. return [];
  38. },
  39. },
  40. },
  41. setup() {
  42. const appStore = useAppStore();
  43. const handleChange = ({ key, value }: { key: string; value: unknown }) => {
  44. if (value && key === 'colorWeek') {
  45. document.body.style.filter = 'invert(80%)';
  46. }
  47. if (!value && key === 'colorWeek') {
  48. document.body.style.filter = 'none';
  49. }
  50. appStore.updateSettings({ [key]: value });
  51. };
  52. return {
  53. handleChange,
  54. };
  55. },
  56. });
  57. </script>
  58. <style scoped lang="less">
  59. .block {
  60. margin-bottom: 24px;
  61. }
  62. .title {
  63. margin: 10px 0;
  64. padding: 0;
  65. font-size: 14px;
  66. }
  67. .switch-wrapper {
  68. display: flex;
  69. align-items: center;
  70. justify-content: space-between;
  71. height: 32px;
  72. }
  73. </style>