<script setup lang="ts"> import { ref, reactive, onMounted, computed } from 'vue'; import { date } from 'quasar'; import { useMessage } from 'src/common/hooks'; import Com from 'src/components'; import { isEmpty, is } from 'src/common/utils'; import { form_config } from '../config'; import type { DialogLayoutProps } from 'src/common/types'; defineExpose({ openDialog, closeDialog, }); const { warn } = useMessage(); const formRef = ref<any>(null); const show = ref(false); const state = reactive({ readonly: false, formConfig: [] as any[], formData: { social: [], } as any, }); const pagestate = reactive<DialogLayoutProps>({ title: '添加', }); const sexOpt = reactive([ { label: '男', value: 1, }, { label: '女', value: 0, }, ]); const socialOpt = reactive([ { value: 'instagram', label: 'Instagram', icon: 'bi-instagram', }, { value: 'weibo', label: '微博', icon: 'bi-sina-weibo', }, { value: 'wechat', label: '微信', icon: 'bi-wechat', }, { value: 'qq', label: 'QQ', icon: 'bi-tencent-qq', }, { value: 'twitter', label: 'Twitter', icon: 'bi-twitter', }, ]); const days = computed(() => { const DATE = state.formData.dateRange; if (isEmpty(DATE)) { return ''; } else { let re; if (is.object(DATE)) { const date1 = new Date(DATE.from); const date2 = new Date(DATE.to); const unit = 'days'; const diff = date.getDateDiff(date2, date1, unit); re = diff + 1; } else { re = 1; } return re; } }); onMounted(() => { initFormConfig(); }); function initDialog() { state.formData = { social: [], }; } function initFormConfig() { state.formConfig = [...form_config]; } function openDialog() { show.value = true; } function closeDialog() { show.value = false; initDialog(); } function onSave() { const { formData } = state; formRef.value.validate().then((suc: any) => { if (!suc) return; if (isEmpty(formData.sex)) return warn('性别必填'); if (formData.social.length < 1) return warn('至少选择一个社交平台'); console.log('formData >>>>', formData); closeDialog(); }); } function onCancel() { closeDialog(); } </script> <template> <q-dialog v-model="show" persistent> <Com.DialogLayout v-bind="pagestate" @onOk="onSave" @onCancel="onCancel"> <Com.MyForm ref="formRef" dense :readonly="state.readonly" :config="state.formConfig" v-model="state.formData" > <template #sex> <div class="item-content"> <div class="label-title text-required">性别</div> <div class="label-content"> <q-option-group v-model="state.formData.sex" :options="sexOpt" color="primary" inline :disable="state.readonly" /> </div> </div> </template> <template #days> <div class="item-content"> <div class="label-title text-required">天数</div> <div class="label-content q-pl-sm">{{ days }}</div> </div> </template> <template #social> <div class="item-content form-label-padding-bottom"> <div class="label-title text-required">社交</div> <div class="label-content"> <q-option-group v-model="state.formData.social" type="checkbox" :options="socialOpt" inline :disable="state.readonly" > <template v-slot:label="opt"> <div class="row items-center"> <q-icon :name="opt.icon" size="1.5em" class="q-mr-sm" color="grey-8" /> <span>{{ opt.label }}</span> </div> </template> </q-option-group> </div> </div> </template> </Com.MyForm> </Com.DialogLayout> </q-dialog> </template> <style lang="scss" scoped> .item-content { width: 100%; display: flex; flex-direction: column; flex-wrap: nowrap; } .label-title { height: 22px; font-size: 14px; line-height: 22px; color: rgba(0, 0, 0, 0.871); margin-bottom: 2px; display: inline-block; } .label-content { height: 40px; min-height: 40px; flex: 1; display: flex; flex-direction: row; align-items: center; background-color: rgba(0, 0, 0, 0.05); border-radius: 4px 4px 0 0; } </style>