V-model="dateRange" value-format="YYYY-MM-DD HH:mm:ss" type="daterange" range-separator="_" unlink-panels start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" ></el-date-picker> </el-config-provider> </el-form-item> <el-form-item label="归属机构" prop="brchno"> <el-select v-model="orgselect"filterable_placeholder="请输入归属机构" style="width:20opx"> <el-input v-model="filterTextOrg" placeholder="输入关键字进行过滤" clearable Qinput="handleFilterOrgsTreeSelect" style="margin: 10px;width: 80%"</el-input> <el-option style="height:auto;background-color: #ff;"> <el-tree :data="orgoptions" :props="{ value: "id', label: "label', children: 'children'}" value-key="id" node-key="id" placeholder="请选择机构" :check-strictly show-checkbox ref="orgTree" highlight-current acheck-change="handleCheckChangeOrg" :filter-node-method="filterNode" L </el-option>根据这些代码来修改前面的问题 </el-select> </el-form-item> <el-form-itemLabel="设备编号"prop="jjh">
时间: 2025-07-21 19:54:00 浏览: 2
<think>根据提供的代码片段,我们需要修改之前的解决方案,因为归属机构字段使用了树形选择(el-tree)而不是简单的输入或选择。同时,设备编号(设备编号)等字段也需要整合进去。
修改点:
1. 归属机构(orgselect)是一个树形选择组件,它的值通过树形结构的选中节点获取。因此,在验证时,我们需要检查orgselect是否有选中的值(注意:树形选择可能支持多选,但根据代码中`check-strictly`和`show-checkbox`,这里可能是单选还是多选?从`handleCheckChangeOrg`方法名看,可能是通过勾选改变,但具体需要看实现。不过,验证逻辑上,我们只需要判断它是否有选中的值即可)。
2. 其他字段(设备编号、设备类型、卡号)保持不变。
由于原问题要求:除了时间范围,至少选择归属机构、设备编号、设备类型、卡号中的一个。
因此,我们需要在自定义验证函数中检查:
- 归属机构(orgselect)是否有值(可能是数组,也可能是单个值,取决于树形选择的配置)
- 设备编号(jjh)是否有值
- 设备类型(deviceType)是否有值
- 卡号(cardNum)是否有值
注意:原代码片段中,设备编号的prop是"jjh",所以表单数据中设备编号字段应该是jjh。
修改后的表单数据对象:
form: {
time: [], // 时间范围
brchno: '', // 归属机构的值(注意:原代码中归属机构的prop是brchno,但v-model绑定的是orgselect?这里需要统一)
jjh: '', // 设备编号
deviceType: '', // 设备类型
cardNum: '' // 卡号
}
但是,观察代码片段,归属机构的el-select绑定的是orgselect,而el-form-item的prop是brchno。这可能导致不一致。我们需要调整:
方案1:将el-form-item的prop改为orgselect,并在rules中定义orgselect的验证规则。
方案2:将v-model改为form.brchno,保持表单数据统一。
为了保持表单数据的统一性,建议使用方案2,即:
<el-select v-model="form.brchno" ...>
但是,原代码片段中使用了树形选择,并且有自定义的过滤和选中处理,所以我们需要将树形选择的选中值同步到form.brchno中。
由于原代码片段不完整,我们假设已经通过事件(如check-change)将选中的节点值赋给了form.brchno(可能是选中的节点id数组,或者单个id,根据业务)。
因此,修改后的验证函数需要检查:
- form.time 必须存在(时间范围)
- 并且 form.brchno, form.jjh, form.deviceType, form.cardNum 至少有一个非空。
注意:空数组(如多选但没有选)视为空,空字符串视为空。
修改后的验证函数:
const validateAtLeastOne = (rule, value, callback) => {
// 注意:form.brchno可能是数组(多选)或字符串(单选),我们通过判断长度来确定是否为空
const brchnoFilled = Array.isArray(form.brchno) ? form.brchno.length > 0 : !!form.brchno;
const jjhFilled = !!form.jjh;
const deviceTypeFilled = !!form.deviceType;
const cardNumFilled = !!form.cardNum;
if (!brchnoFilled && !jjhFilled && !deviceTypeFilled && !cardNumFilled) {
callback(new Error('请至少填写归属机构、设备编号、设备类型或卡号中的一个'));
} else {
callback();
}
};
另外,时间范围是必填的,所以保留原来的规则。
由于归属机构使用了树形选择,其值可能是一个数组(多选)或字符串(单选)。这里根据实际业务,如果是多选,则form.brchno应该是数组;单选可能是字符串或数组。但为了统一,建议在单选时也使用数组(但这样可能不合适,因为单选通常是一个值)。所以,我们需要根据实际配置来处理。
根据代码片段,树形选择使用了`show-checkbox`,所以可能是多选。但原代码中`check-strictly`属性(注意:原代码中写的是`:check-strictly`,没有绑定值,可能默认true)表示父子节点没有关联,并且单选还是多选取决于是否配置了`multiple`。但原代码中没有multiple属性,所以可能是单选?实际上,树形选择在el-option内,所以它不会显示多选样式,而是以下拉树的形式出现,一般单选比较常见。
因此,我们假设这里归属机构是单选,那么form.brchno应该是一个值(节点id)。那么验证时只需要判断form.brchno不为空字符串即可。
但是,由于代码片段不完整,我们无法确定。所以,为了通用性,我们按照上面的验证函数,同时处理数组和字符串。
现在,我们修改模板代码,将归属机构和其他字段整合到之前的模板中,并调整验证规则。
注意:原代码片段中,归属机构的el-select内部有一个el-input用于过滤,还有一个el-tree用于展示树形结构。这种结构在Element Plus中不是标准用法,可能会导致一些问题。通常,树形选择可以使用`<el-tree-select>`(但Element Plus没有原生的树形选择组件,所以常用这种组合方式)。
我们保持原代码片段的结构,但将v-model绑定到form.brchno,并处理树形选择的事件。
由于原代码片段不完整,我们只关注验证部分。因此,我们假设已经通过事件将选中的节点id赋值给form.brchno。
修改后的完整代码示例:
注意:以下代码中,我们只关注表单结构和验证逻辑,树形选择的具体实现(如数据加载、过滤、选中事件)需要根据实际情况补充。</think>根据您提供的代码片段,我将修改前面的解决方案,整合树形机构选择组件并确保验证逻辑正常工作。以下是完整实现:
```vue
<template>
<el-form
ref="formRef"
:model="form"
:rules="rules"
label-width="120px"
>
<!-- 时间范围选择 -->
<el-form-item label="时间范围" prop="dateRange">
<el-date-picker
v-model="form.dateRange"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
range-separator="_"
unlink-panels
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[
new Date(2000, 1, 1, 0, 0, 0),
new Date(2000, 1, 1, 23, 59, 59)
]"
/>
</el-form-item>
<!-- 树形机构选择 -->
<el-form-item label="归属机构" prop="brchno">
<el-select
v-model="form.brchno"
filterable
placeholder="请输入归属机构"
style="width: 200px"
clearable
@clear="handleClearOrg"
>
<el-option style="height: auto; background-color: #fff; padding: 0">
<div style="padding: 10px">
<el-input
v-model="filterTextOrg"
placeholder="输入关键字进行过滤"
clearable
@input="handleFilterOrgsTreeSelect"
style="margin-bottom: 10px; width: 100%"
/>
<el-tree
ref="orgTree"
:data="orgOptions"
:props="{ value: 'id', label: 'label', children: 'children' }"
node-key="id"
:filter-node-method="filterNode"
:check-strictly="true"
show-checkbox
@check="handleCheckChangeOrg"
highlight-current
style="max-height: 300px; overflow: auto"
/>
</div>
</el-option>
</el-select>
</el-form-item>
<!-- 其他字段 -->
<el-form-item label="设备编号" prop="jjh">
<el-input v-model="form.jjh" placeholder="请输入设备编号" />
</el-form-item>
<el-form-item label="设备类型" prop="deviceType">
<el-select v-model="form.deviceType" placeholder="请选择">
<el-option label="类型A" value="A" />
<el-option label="类型B" value="B" />
</el-select>
</el-form-item>
<el-form-item label="卡号" prop="cardNum">
<el-input v-model="form.cardNum" placeholder="请输入卡号" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';
const formRef = ref(null);
const orgTree = ref(null);
const filterTextOrg = ref('');
// 表单数据
const form = reactive({
dateRange: [],
brchno: null, // 机构ID(单选)
jjh: '',
deviceType: '',
cardNum: ''
});
// 模拟机构数据
const orgOptions = ref([
{
id: 1,
label: '总公司',
children: [
{ id: 11, label: '分公司A' },
{ id: 12, label: '分公司B' }
]
},
{
id: 2,
label: '区域中心',
children: [
{ id: 21, label: '分中心X' },
{ id: 22, label: '分中心Y' }
]
}
]);
// 树形组件过滤方法
const filterNode = (value, data) => {
if (!value) return true;
return data.label.includes(value);
};
// 监听过滤文本变化
watch(filterTextOrg, (val) => {
orgTree.value?.filter(val);
});
// 处理机构选择变化
const handleCheckChangeOrg = (checkedNode, { checkedKeys }) => {
if (checkedKeys.length > 0) {
form.brchno = checkedKeys[0]; // 单选模式取第一个
// 获取选中的节点对象
const node = orgTree.value.getNode(checkedKeys[0]);
if (node && node.data) {
console.log('选中的机构:', node.data.label);
}
} else {
form.brchno = null;
}
};
// 清除机构选择
const handleClearOrg = () => {
form.brchno = null;
orgTree.value?.setCheckedKeys([]);
};
// 自定义验证规则:至少填写时间外的其他一个字段
const validateAtLeastOne = (rule, value, callback) => {
const { brchno, jjh, deviceType, cardNum } = form;
if (!brchno && !jjh && !deviceType && !cardNum) {
callback(new Error('请至少填写归属机构、设备编号、设备类型或卡号中的一个'));
} else {
callback();
}
};
// 表单验证规则
const rules = {
dateRange: [
{
type: 'array',
required: true,
message: '请选择时间范围',
trigger: 'change'
}
],
// 虚拟字段用于联合验证
atLeastOne: [
{ validator: validateAtLeastOne, trigger: 'change' }
]
};
// 提交表单
const submitForm = () => {
formRef.value.validate((valid) => {
if (valid) {
// 准备提交数据
const submitData = {
startTime: form.dateRange[0],
endTime: form.dateRange[1],
orgId: form.brchno,
deviceCode: form.jjh,
deviceType: form.deviceType,
cardNumber: form.cardNum
};
console.log('提交数据:', submitData);
alert('表单验证通过,准备提交');
} else {
console.log('表单验证失败');
return false;
}
});
};
// 重置表单
const resetForm = () => {
formRef.value.resetFields();
form.brchno = null;
orgTree.value?.setCheckedKeys([]);
};
</script>
```
### 关键修改说明
1. **树形机构选择集成**:
- 使用 `el-tree` 嵌套在 `el-select` 中实现树形选择
- 添加搜索过滤功能,通过 `filter-node-method` 实现
- 使用 `check-strictly` 实现父子节点不关联
- 通过 `@check` 事件处理选择变化
2. **机构选择数据处理**:
```javascript
const handleCheckChangeOrg = (checkedNode, { checkedKeys }) => {
if (checkedKeys.length > 0) {
form.brchno = checkedKeys[0]; // 单选模式
const node = orgTree.value.getNode(checkedKeys[0]);
// 可以获取选中节点的完整数据
} else {
form.brchno = null;
}
};
```
3. **验证规则调整**:
```javascript
const validateAtLeastOne = (rule, value, callback) => {
const { brchno, jjh, deviceType, cardNum } = form;
if (!brchno && !jjh && !deviceType && !cardNum) {
callback(new Error('请至少填写一个字段'));
} else {
callback();
}
};
```
4. **重置逻辑增强**:
```javascript
const resetForm = () => {
formRef.value.resetFields();
form.brchno = null; // 额外重置机构选择
orgTree.value?.setCheckedKeys([]); // 清空树形选择
};
```
5. **时间选择器配置**:
- 使用 `value-format="YYYY-MM-DD HH:mm:ss"` 确保时间格式
- 设置 `:default-time` 提供默认时间值
- `unlink-panels` 允许左右面板独立选择
### 注意事项
1. **树形选择实现细节**:
- 单选模式通过只取第一个选中键实现
- 使用 `getNode` 方法可以获取选中节点的完整数据
- `check-strictly` 确保父子节点选择不联动
2. **性能优化**:
- 使用 `max-height` 限制树形组件高度
- 添加滚动条防止数据过多时页面溢出
- 通过 `watch` 监听过滤文本变化,避免频繁重渲染
3. **表单验证**:
- 虚拟字段 `atLeastOne` 触发联合验证
- `trigger: 'change'` 确保实时验证
- 机构选择值使用 `null` 表示未选择
4. **数据提交**:
- 时间范围拆分为 startTime 和 endTime
- 机构提交 ID 值,可根据需要提交完整对象
- 保持字段命名与后端接口一致
阅读全文
相关推荐


















