如何在下拉列表中映射存在层级差异的JSON数据(含无院校场景)
层级-院校-项目联动下拉列表实现方案
需求回顾
需要将给定的JSON数据映射为三级联动下拉列表:
- 层级(Level)包含UG、PG、PHD、DIPLOMA
- 院校(School)仅在UG、PG、DIPLOMA层级存在,PHD层级无院校
- 所有层级都包含对应的项目(Program)
数据映射逻辑
先明确给定JSON的结构差异:
- 非PHD层级(UG/PG/DIPLOMA):包含
levelName和school数组,每个school下又有program数组 - PHD层级:仅包含
levelName和直接的program数组
核心是根据选中的层级类型,动态决定是否渲染院校下拉,并正确关联对应的项目数据。
联动条件编写逻辑
- 层级下拉初始化:遍历
programList.level数组,将每个levelName作为下拉选项值。 - 层级选择后的分支判断:
- 如果选中的层级是
PHD:直接跳过院校下拉,加载该层级下的program数组作为项目下拉选项 - 如果是其他层级:加载该层级对应的
school数组作为院校下拉选项
- 如果选中的层级是
- 院校选择后的逻辑(仅非PHD层级触发):选中某一院校后,加载该院校下的
program数组作为项目下拉选项
代码示例(React 实现)
import { useState } from 'react'; const programList = { level: [ { levelName: "UG", school: [{ schoolName: "XYZ", program: [{ programName: "PQR" }] }] }, { levelName: "PG", school: [{ schoolName: "XYZ", program: [{ programName: "PQR" }] }] }, { levelName: "PHD", program: [{ programName: "PQR" }] }, { levelName: "DIPLOMA", school: [{ schoolName: "ABC", program: [{ programName: "DEF" }] }] } ] }; export default function ProgramDropdown() { const [selectedLevel, setSelectedLevel] = useState(''); const [selectedSchool, setSelectedSchool] = useState(''); const [selectedProgram, setSelectedProgram] = useState(''); // 获取当前选中层级的详情 const currentLevel = programList.level.find(item => item.levelName === selectedLevel); return ( <div> {/* 层级下拉 */} <select value={selectedLevel} onChange={(e) => { setSelectedLevel(e.target.value); // 切换层级时重置院校和项目选择 setSelectedSchool(''); setSelectedProgram(''); }}> <option value="">请选择层级</option> {programList.level.map(level => ( <option key={level.levelName} value={level.levelName}>{level.levelName}</option> ))} </select> {/* 院校下拉:仅非PHD层级显示 */} {selectedLevel && selectedLevel !== 'PHD' && ( <select value={selectedSchool} onChange={(e) => { setSelectedSchool(e.target.value); setSelectedProgram(''); }}> <option value="">请选择院校</option> {currentLevel?.school?.map(school => ( <option key={school.schoolName} value={school.schoolName}>{school.schoolName}</option> ))} </select> )} {/* 项目下拉 */} {selectedLevel && ( <select value={selectedProgram} onChange={(e) => setSelectedProgram(e.target.value)}> <option value="">请选择项目</option> {/* PHD层级直接取program,非PHD层级取选中院校的program */} {selectedLevel === 'PHD' ? ( currentLevel?.program?.map(program => ( <option key={program.programName} value={program.programName}>{program.programName}</option> )) ) : ( currentLevel?.school?.find(school => school.schoolName === selectedSchool)?.program?.map(program => ( <option key={program.programName} value={program.programName}>{program.programName}</option> )) )} </select> )} </div> ); }
代码示例(原生JS 实现)
<div> <select id="levelSelect"> <option value="">请选择层级</option> </select> <select id="schoolSelect" style="display:none;"> <option value="">请选择院校</option> </select> <select id="programSelect"> <option value="">请选择项目</option> </select> </div> <script> const programList = { level: [ { levelName: "UG", school: [{ schoolName: "XYZ", program: [{ programName: "PQR" }] }] }, { levelName: "PG", school: [{ schoolName: "XYZ", program: [{ programName: "PQR" }] }] }, { levelName: "PHD", program: [{ programName: "PQR" }] }, { levelName: "DIPLOMA", school: [{ schoolName: "ABC", program: [{ programName: "DEF" }] }] } ] }; const levelSelect = document.getElementById('levelSelect'); const schoolSelect = document.getElementById('schoolSelect'); const programSelect = document.getElementById('programSelect'); // 初始化层级下拉 programList.level.forEach(level => { const option = document.createElement('option'); option.value = level.levelName; option.textContent = level.levelName; levelSelect.appendChild(option); }); // 层级选择事件 levelSelect.addEventListener('change', function() { const selectedLevel = this.value; schoolSelect.style.display = selectedLevel && selectedLevel !== 'PHD' ? 'inline-block' : 'none'; // 重置院校和项目 schoolSelect.value = ''; programSelect.innerHTML = '<option value="">请选择项目</option>'; if (!selectedLevel) return; const currentLevel = programList.level.find(item => item.levelName === selectedLevel); // 非PHD层级,加载院校选项 if (selectedLevel !== 'PHD') { schoolSelect.innerHTML = '<option value="">请选择院校</option>'; currentLevel.school.forEach(school => { const option = document.createElement('option'); option.value = school.schoolName; option.textContent = school.schoolName; schoolSelect.appendChild(option); }); } else { // PHD层级直接加载项目选项 currentLevel.program.forEach(program => { const option = document.createElement('option'); option.value = program.programName; option.textContent = program.programName; programSelect.appendChild(option); }); } }); // 院校选择事件 schoolSelect.addEventListener('change', function() { const selectedLevel = levelSelect.value; const selectedSchool = this.value; programSelect.innerHTML = '<option value="">请选择项目</option>'; if (!selectedSchool) return; const currentLevel = programList.level.find(item => item.levelName === selectedLevel); const targetSchool = currentLevel.school.find(school => school.schoolName === selectedSchool); targetSchool.program.forEach(program => { const option = document.createElement('option'); option.value = program.programName; option.textContent = program.programName; programSelect.appendChild(option); }); }); </script>
内容的提问来源于stack exchange,提问作者Urmila Sirase
相关产品推荐
相关产品推荐

