为满足其他页面(如面试不通过原因登记、重点关注人员管理、岗位推荐等)需要选择人员的场景,基于人员信息列表的查询表单和数据表格,封装了一套可复用的人员选择器组件,支持单选/多选,并通过 v-model 将选中的完整人员记录返回给父组件。
文件路径(相对于项目根目录 zjrs-jeecgBoot) |
操作 | 说明 |
|---|---|---|
jeecgboot-vue3/src/views/recruitment/personal/components/PersonalInfoSelectorModal.vue |
新建 | 选择器弹窗组件,包含查询表单和 BasicTable 表格,支持单/多选行,通过 @select 事件返回选中记录 |
jeecgboot-vue3/src/views/recruitment/personal/components/PersonalInfoSelector.vue |
新建 | 带输入框载体的组合组件,封装了触发输入框 + 弹窗的完整交互,通过 v-model 双向绑定选中数据 |
PersonalInfoSelector.vue ← 对外暴露的入口组件
└─ 输入框(只读,点击触发弹窗)
└─ PersonalInfoSelectorModal.vue ← 内部弹窗
├─ 查询表单(姓名、性别、学历、户口所在地、现居住地、年龄范围、求职人员类别、求职状态、数据来源)
└─ BasicTable(含字典渲染、行选择、分页)
在任意父页面引入 PersonalInfoSelector.vue 即可:
<template>
<!-- 多选 -->
<PersonalInfoSelector v-model="selectedPersons" selectionType="multiple" width="360" />
<!-- 单选 -->
<PersonalInfoSelector v-model="selectedPerson" selectionType="single" width="300" placeholder="请选择单个人员" />
</template>
<script setup>
import PersonalInfoSelector from '/@/views/recruitment/personal/components/PersonalInfoSelector.vue';
// 多选:v-model 绑定的值为人员记录数组
const selectedPersons = ref([]);
// 单选:v-model 绑定的值为人员记录对象或 null
const selectedPerson = ref(null);
</script>
以下为面试不通过原因登记表单中的使用方式(单选模式,选择人员后自动填充关联字段):
<template>
<a-col :span="12">
<a-form-item label="姓名" name="fullName">
<PersonalInfoSelector
v-model:value="selectedPerson"
selectionType="single"
placeholder="请选择人员"
:allowClear="false"
/>
</a-form-item>
</a-col>
</template>
<script setup>
import PersonalInfoSelector from '/@/views/recruitment/personal/components/PersonalInfoSelector.vue';
import { useDict } from '/@/hooks/dictionary/useDict';
const { getDictText } = useDict(['Gender']);
// 人员选择器绑定值(单选模式,值为人员记录对象或 null)
const selectedPerson = ref(null);
// 监听人员选择,自动填充性别、年龄、户口所在地等字段
watch(selectedPerson, (val) => {
if (val) {
formData.fullName = val.fullName || '';
formData.gender = getDictText('Gender', val.gender) || '';
formData.age = calcAge(val.birthDate);
formData.householdAreaName = val.householdAreaName || '';
formData.personalId = val.id || '';
} else {
formData.fullName = '';
formData.gender = '';
formData.age = '';
formData.householdAreaName = '';
formData.personalId = '';
}
});
// 编辑时恢复已选人员状态
// 在 edit() 方法中根据已有数据构造 selectedPerson 对象,组件会自动回显
if (formData.fullName) {
selectedPerson.value = {
id: formData.personalId || '',
fullName: formData.fullName,
gender: formData.gender || '',
age: formData.age || '',
householdAreaName: formData.householdAreaName || '',
};
}
</script>
完整实现参见
jeecgboot-vue3/src/views/interviewfail/reason/components/InterviewFailReasonForm.vue
带触发输入框的完整选择器,直接用于表单中。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue |
any |
— | v-model 绑定值(标准写法)。单选传对象 { id, fullName, ... },多选传数组 |
value |
any |
— | v-model:value 绑定值(兼容命名写法),与 modelValue 二选一 |
selectionType |
'single' \| 'multiple' |
'multiple' |
选择模式 |
placeholder |
string |
'请选择人员' |
输入框占位文本 |
width |
string \| number |
— | 输入框宽度(如 '300px' 或 300) |
allowClear |
boolean |
true |
是否允许输入框右侧一键清除已选项 |
| 事件 | 参数 | 说明 |
|---|---|---|
update:modelValue |
value: any |
v-model 更新事件 |
update:value |
value: any |
v-model:value 更新事件(兼容写法) |
change |
records: any[] |
选中记录变化时触发,始终返回数组 |
selectedKeys 和 selectedRecords 实现)仅供 PersonalInfoSelector.vue 内部使用,也可单独引用以自定义触发方式。
| 方法 | 参数 | 说明 |
|---|---|---|
open(config) |
{ selectionType?: 'single' \| 'multiple', selectedKeys?: (string \| number)[], selectedRecords?: any[] } |
打开弹窗。selectionType 默认 'multiple';selectedKeys 用于回显勾选状态;selectedRecords 用于回显勾选并提供完整的选中数据 |
| 事件 | 参数 | 说明 |
|---|---|---|
select |
records: any[] |
确认选择时触发,返回选中行的完整记录数组 |
<template>
<a-button @click="openSelector">选择人员</a-button>
<PersonalInfoSelectorModal ref="selectorModal" @select="handleSelect" />
</template>
<script setup>
import PersonalInfoSelectorModal from './components/PersonalInfoSelectorModal.vue';
const selectorModal = ref();
function openSelector() {
selectorModal.value.open({ selectionType: 'single' });
}
function handleSelect(records) {
console.log('选中的人员:', records);
}
</script>
useDict 预加载,表格中性别、学历、民族、求职状态等字段自动转为中文显示。computed 动态计算 rowSelection,根据 selectionType 切换为 checkbox(多选)或 radio(单选)。useCustomSelection 自封装选择列(非 ant-design-vue 原生 rowSelection),弹窗打开时通过 useTable 返回的 setSelectedRowKeys API 程序化设置选中行,确保自定义选择列正确回显。selectedKeys 和 selectedRecords 一并传入,确保勾选状态和确认数据完整。beforeFetch 钩子中自动将输入的年龄范围转换为出生日期范围传给后端。allowClear 为 true 时,清除按钮将 v-model 重置为空值(单选为 null,多选为 [])。open() 中先设置 visible = true,再通过 nextTick 等待弹窗 DOM 渲染完成后执行 reload() 和 setSelectedRowKeys(),避免表格实例未就绪导致报错。