tips: 监听radio的变化以及获取radio选中值

<!-- listen to the OperatingSystem radios change -->

$("input:radio[name='operatingSystem']").change(function(){

    var operatingSystem = $("input[name='operatingSystem']:checked").val(); 

    alert(operatingSystem);

});


<template> <!-- drawer --> <template v-if="modalConfig?.component === 'drawer'"> <el-drawer v-model="modalVisible" :append-to-body="true" v-bind="modalConfig?.drawer" @close="handleCloseModal" > <!-- 表单 --> <el-form ref="formRef" label-width="auto" v-bind="modalConfig?.form" :model="formData" :rules="formRules" :disabled="modalConfig?.formDisabled" > <el-row :gutter="20"> <template v-for="item in formItems" :key="item.prop"> <el-col v-show="!item.hidden" v-bind="item.col"> <el-form-item :label="item.label" :prop="item.prop"> <!-- Label --> <template v-if="item.tips" #label> <span> {{ item.label }} <el-tooltip placement="bottom" effect="light" :content="item.tips + ''" :raw-content="true" > <el-icon style="vertical-align: -0.15em" size="16"> <QuestionFilled /> </el-icon> </el-tooltip> </span> </template> <!-- Input 输入框 --> <template v-if="item.type === 'input' || item.type === undefined"> <el-input v-model="formData[item.prop]" v-bind="item.attrs" /> </template> <!-- Select 选择器 --> <template v-else-if="item.type === 'select'"> <el-select v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-option v-bind="option" /> </template> </el-select> </template> <!-- Radio 单选框 --> <template v-else-if="item.type === 'radio'"> <el-radio-group v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-radio v-bind="option" /> </template> </el-radio-group> </template> <!-- switch 开关 --> <template v-else-if="item.type === 'switch'"> <el-switch v-model="formData[item.prop]" inline-prompt v-bind="item.attrs" /> </template> <!-- Checkbox 多选框 --> <template v-else-if="item.type === 'checkbox'"> <el-checkbox-group v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-checkbox v-bind="option" /> </template> </el-checkbox-group> </template> <!-- Input Number 数字输入框 --> <template v-else-if="item.type === 'input-number'"> <el-input-number v-model="formData[item.prop]" v-bind="item.attrs" /> </template> <!-- TreeSelect 树形选择 --> <template v-else-if="item.type === 'tree-select'"> <FkSelectTree v-model="formData[item.prop]" v-bind="item.attrs" :multiple="item.attrs?.multiple" /> </template> <!-- DatePicker 日期选择器 --> <template v-else-if="item.type === 'date-picker'"> <el-date-picker v-model="formData[item.prop]" v-bind="item.attrs" /> </template> <!-- Text 文本 --> <template v-else-if="item.type === 'text'"> <el-text v-bind="item.attrs"> {{ formData[item.prop] }} </el-text> </template> <!-- 格式化代码集 --> <template v-else-if="item.type === 'sys-code'"> <FkSysCode v-model="formData[item.prop]" :sysCode="item.sysCodeSetCode" v-bind="item.attrs" /> </template> <!-- 自定义 --> <template v-else-if="item.type === 'custom'"> <slot :name="item.slotName ?? item.prop" :prop="item.prop" :form-data="formData" :attrs="item.attrs" /> </template> </el-form-item> </el-col> </template> </el-row> </el-form> <!-- 弹窗底部操作按钮 --> <template #footer> <div v-if="!formDisable"> <el-button type="primary" @click="handleSubmit">确 定1</el-button> <el-button @click="handleClose">取 消</el-button> </div> <div v-else> <el-button @click="handleClose">关闭</el-button> </div> </template> </el-drawer> </template> <!-- dialog --> <template v-else> <el-dialog v-model="modalVisible" :align-center="true" :append-to-body="true" width="70vw" v-bind="modalConfig?.dialog" style="padding-right: 0" @close="handleCloseModal" > <!-- 滚动 --> <el-scrollbar max-height="60vh"> <!-- 表单 --> <el-form ref="formRef" label-width="auto" v-bind="modalConfig.form" style="padding-right: var(--el-dialog-padding-primary)" :model="formData" :rules="formRules" > <el-row :gutter="20"> <template v-for="item in formItems" :key="item.prop"> <el-col v-show="!item.hidden" v-bind="item.col"> <el-form-item :label="item.label" :prop="item.prop"> <!-- Label --> <template v-if="item.tips" #label> <span> {{ item.label }} <el-tooltip placement="bottom" effect="light" :content="item.tips + ''" :raw-content="true" > <el-icon style="vertical-align: -0.15em" size="16"> <QuestionFilled /> </el-icon> </el-tooltip> </span> </template> <!-- Input 输入框 --> <template v-if="item.type === 'input' || item.type === undefined"> <el-input v-model="formData[item.prop]" v-bind="item.attrs" clearable /> </template> <!-- Select 选择器 --> <template v-else-if="item.type === 'select'"> <el-select v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-option v-bind="option" /> </template> </el-select> </template> <!-- Radio 单选框 --> <template v-else-if="item.type === 'radio'"> <el-radio-group v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-radio v-bind="option" /> </template> </el-radio-group> </template> <!-- switch 开关 --> <template v-else-if="item.type === 'switch'"> <el-switch v-model="formData[item.prop]" inline-prompt v-bind="item.attrs" /> </template> <!-- Checkbox 多选框 --> <template v-else-if="item.type === 'checkbox'"> <el-checkbox-group v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-checkbox v-bind="option" /> </template> </el-checkbox-group> </template> <!-- Input Number 数字输入框 --> <template v-else-if="item.type === 'input-number'"> <el-input-number v-model="formData[item.prop]" v-bind="item.attrs" /> </template> <!-- TreeSelect 树形选择 --> <template v-else-if="item.type === 'tree-select'"> <FkSelectTree v-model="formData[item.prop]" v-bind="item.attrs" :multiple="item.attrs?.multiple" /> </template> <!-- DatePicker 日期选择器 --> <template v-else-if="item.type === 'date-picker'"> <el-date-picker v-model="formData[item.prop]" v-bind="item.attrs" /> </template> <!-- Text 文本 --> <template v-else-if="item.type === 'text'"> <el-text v-bind="item.attrs"> {{ formData[item.prop] }} </el-text> </template> <!-- 格式化代码集 --> <template v-else-if="item.type === 'sys-code'"> <FkSysCode v-model="formData[item.prop]" :sys-code="item.sysCodeSetCode" v-bind="item.attrs" /> </template> <!-- 自定义 --> <template v-else-if="item.type === 'custom'"> <slot :name="item.slotName ?? item.prop" :prop="item.prop" :form-data="formData" :attrs="item.attrs" /> </template> </el-form-item> </el-col> </template> </el-row> </el-form> </el-scrollbar> <!-- 弹窗底部操作按钮 --> <template #footer> <div style="padding-right: var(--el-dialog-padding-primary)"> <el-button type="primary" @click="handleSubmit">确 定</el-button> <el-button @click="handleClose">取 消</el-button> </div> </template> </el-dialog> </template> </template> <script setup lang="ts"> import { useThrottleFn } from "@vueuse/core"; import type { FormInstance, FormRules } from "element-plus"; import { nextTick, reactive, ref, watch, watchEffect } from "vue"; import type { IModalConfig, IObject, IContentConfig } from "./types"; // 定义接收的属性 const props = defineProps<{ modalConfig: IModalConfig; contentConfig?: IContentConfig; }>(); // 自定义事件 const emit = defineEmits<{ submitClick: []; }>(); const pk = props.modalConfig?.pk ?? "id"; const modalVisible = ref(false); const formRef = ref<FormInstance>(); let formItems = reactive(props.modalConfig.formItems); let formItemChanges = ref<Record<string, any>>({}); const formData = reactive<IObject>({}); const formRules = ref<FormRules>({}); const formDisable = ref(false); const prepareFuncs = []; for (const item of formItems) { item.initFn && item.initFn(item); formData[item.prop] = item.initialValue ?? ""; formRules.value[item.prop] = item.rules ?? []; if (item.watch !== undefined) { prepareFuncs.push(() => { watch( () => formData[item.prop], (newValue, oldValue) => { item.watch && item.watch(newValue, oldValue, formData, formItems); } ); }); } if (item.computed !== undefined) { prepareFuncs.push(() => { watchEffect(() => { item.computed && (formData[item.prop] = item.computed(formData)); }); }); } if (item.watchEffect !== undefined) { prepareFuncs.push(() => { watchEffect(() => { item.watchEffect && item.watchEffect(formData); }); }); } if (item.change) { formItemChanges.value[item.prop] = item.change; } } prepareFuncs.forEach((func) => func()); // 获取表单数据 function getFormData(key?: string) { return key === undefined ? formData : (formData[key] ?? undefined); } // 设置表单 function setFormData(data: IObject) { for (const key in formData) { if (Object.prototype.hasOwnProperty.call(formData, key) && key in data) { formData[key] = data[key]; } } if (Object.prototype.hasOwnProperty.call(data, pk)) { formData[pk] = data[pk]; } } // 设置表单项 function setFormItemData(key: string, value: any) { formData[key] = value; } // 显示modal function setModalVisible(data: IObject = {}) { modalVisible.value = true; // nextTick解决赋后重置表单无效问题 nextTick(() => { Object.values(data).length > 0 && setFormData(data); }); setupFormWatcher(); } // 表单提交 const handleSubmit = useThrottleFn(() => { formRef.value?.validate((valid: boolean) => { if (valid) { if (typeof props.modalConfig.beforeSubmit === "function") { props.modalConfig.beforeSubmit(formData); } if ( props.contentConfig && props.contentConfig.lefftTree && props.contentConfig.lefftTree.treeKeyName ) { formData[props.contentConfig.lefftTree.treeKeyName] = props.contentConfig?.lefftTree.treeKeyValue; } if (!props.modalConfig.formAction) { ElMessage.error("表单提交未配置"); return; } props.modalConfig.formAction(formData).then(() => { let msg = "操作成功"; if (props.modalConfig.component === "drawer") { if (props.modalConfig.drawer?.title) { msg = `${props.modalConfig.drawer?.title}成功`; } } else { if (props.modalConfig.dialog?.title) { msg = `${props.modalConfig.dialog?.title}成功`; } } ElMessage.success(msg); handleClose(); emit("submitClick"); }); } }); }, 3000); // 取消弹窗 function handleClose() { console.log("取消弹窗"); handleCloseModal(); } // 关闭弹窗 function handleCloseModal() { modalVisible.value = false; formData.value?.resetFields(); formData.value?.clearValidate(); } // 禁用表单--用于详情时候用 function handleDisabled(disable: boolean) { formRef.value?.clearValidate; formDisable.value = disable; props.modalConfig.formDisabled = disable; } // 初始化监听 let formWatcher: (() => void) | null = null; // 监听销毁函数 const setupFormWatcher = () => { if (formWatcher) { formWatcher(); // 清除之前的监听 formWatcher = null; } console.log("setupFormWatcher:"); // 监听指定字段变化 formWatcher = watch( () => props.modalConfig.formItems .filter((formItem) => formItemChanges.value[formItem.prop]) .map((formItem) => ({ prop: formItem.prop, value: formData[formItem.prop], })), (fields) => { formRef.value?.clearValidate(); fields.forEach((field) => { if (!formItemChanges.value[field.prop]) return; console.log("字段变化:", field.prop, field.value); const changeConfig = formItemChanges.value[field.prop]; if (changeConfig.hidden) { const hiddenStates = changeConfig.hidden(formData); props.modalConfig.formItems.forEach((formItem) => { if (hiddenStates[formItem.prop] !== undefined) { formItem.hidden = hiddenStates[formItem.prop]; formRules.value[formItem.prop] = formItem.hidden ? [] : formItem.rules || []; } }); } }); }, { deep: true, immediate: true } ); }; // 弹窗关闭处理 const handleDrawerClose = () => { if (formWatcher) { formWatcher(); // 调用停止监听函数 } formRef.value?.resetFields(); formRef.value?.clearValidate(); }; // 组件卸载时确保停止监听 onUnmounted(() => { handleDrawerClose(); }); // 暴露的属性和方法 defineExpose({ setModalVisible, getFormData, setFormData, setFormItemData, handleDisabled }); </script> <style lang="scss" scoped></style> 优化 监听执行隐藏其他字段后,不需要校验
最新发布
07-17
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值