AngularJS实现下拉框选中项在另一下拉框隐藏的技术问询
嘿,这个需求太贴合实际场景了!我来给你几个不同技术栈的实现方案,你可以根据自己的项目情况选~
原生JavaScript实现方案
这是最基础的实现,不用任何框架,适合纯静态页面或者小项目:
首先写HTML结构:
<select id="group1"> <option value="">-- 选择人员 --</option> </select> <select id="group2"> <option value="">-- 选择人员 --</option> </select>
然后是JS逻辑:
// 共享的人员数据源 const people = ["张三", "李四", "王五", "赵六", "孙七"]; // 获取两个下拉框元素 const group1 = document.getElementById("group1"); const group2 = document.getElementById("group2"); // 初始化下拉框选项 function initDropdowns() { people.forEach(person => { const option1 = document.createElement("option"); option1.value = person; option1.textContent = person; group1.appendChild(option1); const option2 = document.createElement("option"); option2.value = person; option2.textContent = person; group2.appendChild(option2); }); } // 更新目标下拉框的可用选项 function updateAvailableOptions(selectedValue, targetDropdown) { // 先清空现有选项(保留默认空选项) targetDropdown.innerHTML = '<option value="">-- 选择人员 --</option>'; // 过滤出未被选中的人员并添加到目标下拉框 people.forEach(person => { if (person !== selectedValue) { const option = document.createElement("option"); option.value = person; option.textContent = person; targetDropdown.appendChild(option); } }); // 如果目标下拉框当前选中的是被排除的选项,重置为空 if (targetDropdown.value === selectedValue) { targetDropdown.value = ""; } } // 绑定事件监听 group1.addEventListener("change", () => { updateAvailableOptions(group1.value, group2); }); group2.addEventListener("change", () => { updateAvailableOptions(group2.value, group1); }); // 初始化 initDropdowns();
这个方案的好处是零依赖,逻辑清晰:每次选中一个选项,就把另一个下拉框里的该选项移除,同时如果另一个下拉框之前刚好选中了这个选项,会自动重置为空,避免冲突。
Vue 3实现方案
如果你的项目用Vue 3,用响应式和计算属性来实现会更优雅:
<template> <div> <select v-model="selectedGroup1"> <option value="">-- 选择人员 --</option> <option v-for="person in availableForGroup1" :key="person" :value="person"> {{ person }} </option> </select> <select v-model="selectedGroup2"> <option value="">-- 选择人员 --</option> <option v-for="person in availableForGroup2" :key="person" :value="person"> {{ person }} </option> </select> </div> </template> <script setup> import { ref, computed } from 'vue'; // 共享数据源 const people = ["张三", "李四", "王五", "赵六", "孙七"]; // 两个组的选中值 const selectedGroup1 = ref(""); const selectedGroup2 = ref(""); // 计算组1的可用选项(排除组2已选的) const availableForGroup1 = computed(() => { return people.filter(person => person !== selectedGroup2.value); }); // 计算组2的可用选项(排除组1已选的) const availableForGroup2 = computed(() => { return people.filter(person => person !== selectedGroup1.value); }); </script>
Vue的响应式系统会自动帮你处理选项的更新,完全不用手动操作DOM,代码简洁很多,而且维护起来更方便。
React实现方案
对于React项目,可以用useState和useMemo来实现类似的逻辑:
import { useState, useMemo } from 'react'; function PersonAssignment() { // 共享数据源 const people = ["张三", "李四", "王五", "赵六", "孙七"]; // 两个组的选中状态 const [selectedGroup1, setSelectedGroup1] = useState(""); const [selectedGroup2, setSelectedGroup2] = useState(""); // 计算组1的可用选项 const optionsForGroup1 = useMemo(() => { return people.filter(person => person !== selectedGroup2); }, [selectedGroup2]); // 计算组2的可用选项 const optionsForGroup2 = useMemo(() => { return people.filter(person => person !== selectedGroup1); }, [selectedGroup1]); return ( <div> <select value={selectedGroup1} onChange={(e) => setSelectedGroup1(e.target.value)} > <option value="">-- 选择人员 --</option> {optionsForGroup1.map(person => ( <option key={person} value={person}>{person}</option> ))} </select> <select value={selectedGroup2} onChange={(e) => setSelectedGroup2(e.target.value)} > <option value="">-- 选择人员 --</option> {optionsForGroup2.map(person => ( <option key={person} value={person}>{person}</option> ))} </select> </div> ); } export default PersonAssignment;
useMemo可以避免不必要的重复计算,只有当依赖的选中值变化时才重新过滤选项,性能更好。
额外提示
- 如果需要支持多选下拉框,只需要把选中值改成数组,过滤逻辑改成排除数组里的所有元素即可。
- 如果数据源是异步获取的,只需要把初始化逻辑放在数据请求完成后执行就行(比如Vue里放在
onMounted的请求回调中,React放在useEffect里)。
内容的提问来源于stack exchange,提问作者Victor Odera
相关产品推荐
相关产品推荐

