
此部分将详细阐述如何创建一个自定义的 material-ui 多选组件,它包含一个特殊的“全选/取消全选”选项,并能根据当前选择状态动态改变其文本标签。
1.1 组件结构与 Props
该组件 MultiSelectWithCheckbox 接收以下核心 props:
import React from 'react';
import { Checkbox, InputLabel, ListItemIcon, ListItemText, MenuItem, FormControl, Select } from '@material-ui/core';
import { MenuProps, useStyles } from './multiSelectWithCheckboxUtil';
function MultiSelectWithCheckbox(props) {
const classes = useStyles();
// 判断是否所有选项都被选中
const isAllSelected = props.options.length > 0 && props.value.length === props.options.length;
// 处理选择变化的函数
const handleChange = React.useCallback(event => {
const value = event.target.value;
// 如果点击的是“全选/取消全选”选项
if (value[value.length - 1] === 'all') {
// 如果当前已全选,则清空所有选择;否则,选中所有选项
props.onChange(props.value.length === props.options.length ? [] : props.options);
return;
}
// 处理普通选项的选择
props.onChange(value);
}, [props.value, props.options, props.onChange]); // 依赖项应包含所有用到的props
return (
<FormControl className={classes.formControl}>
<InputLabel id='mutiple-select-label' style={{ fontSize: 18 }}>{props.label}</InputLabel>
<Select
labelId='mutiple-select-label'
multiple // 启用多选模式
value={props.value}
onChange={handleChange}
// 自定义渲染已选中的值
renderValue={React.useCallback(selected => selected.join(', '), [])}
MenuProps={MenuProps} // 应用自定义菜单属性
>
{/* “全选/取消全选”选项 */}
<MenuItem
value='all'
classes={{
root: isAllSelected ? classes.selectedAll : '',
}}
>
<ListItemIcon>
<Checkbox
classes={{
indeterminate: classes.indeterminateColor,
}}
checked={isAllSelected} // 全选时选中
// 当部分选中时显示不确定状态
indeterminate={props.value.length > 0 && props.value.length < props.options.length}
/>
</ListItemIcon>
<ListItemText
classes={{ primary: classes.selectAllText }}
// 核心逻辑:根据isAllSelected动态改变文本
primary={isAllSelected ? 'Uncheck all' : 'Check all'}
/>
</MenuItem>
{/* 遍历渲染所有可选选项 */}
{props.options.map(option => (
<MenuItem key={option} value={option}>
<ListItemIcon>
{/* 判断当前选项是否被选中 */}
<Checkbox checked={props.value.indexOf(option) > -1} />
</ListItemIcon>
<ListItemText primary={option} />
</MenuItem>
))}
</Select>
</FormControl>
);
}
export default MultiSelectWithCheckbox;1.2 关键逻辑解析
isAllSelected 状态判断:const isAllSelected = props.options.length > 0 && props.value.length === props.options.length; 这个布尔变量用于判断当前是否所有选项都被选中。它不仅控制“全选”复选框的 checked 状态,更重要的是,它决定了“全选/取消全选”文本标签的显示。
handleChange 事件处理: 当用户点击 MenuItem 时,onChange 事件会被触发。我们通过检查 event.target.value 的最后一个元素是否为 'all' 来判断用户是否点击了“全选/取消全选”选项。
动态文本标签:primary={isAllSelected ? 'Uncheck all' : 'Check all'} 这是实现“全选”和“取消全选”文本动态切换的核心代码。ListItemText 组件的 primary 属性通过三元表达式,根据 isAllSelected 的布尔值,动态地显示“Uncheck all”(取消全选)或“Check all”(全选)。
复选框状态 (Checkbox):
此文件包含组件所需的样式定义和下拉菜单的配置。
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles(theme => ({
formControl: {
width: '100%'
},
indeterminateColor: {
color: '#f50057' // 自定义不确定状态的颜色
},
selectAllText: {
fontWeight: 500 // “全选/取消全选”文本的字体粗细
},
selectedAll: {
'&:hover': {
backgroundColor: 'rgba(0, 0, 0, 0.08)'
},
backgroundColor: 'rgba(0, 0, 0, 0.08)' // 全选选项的背景色
}
}));
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
anchorOrigin: {
horizontal: 'center',
vertical: 'bottom' // 菜单锚点位于选择框底部中心
},
getContentAnchorEl: null, // 确保菜单位置不受内容影响
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, // 菜单最大高度
}
},
transformOrigin: {
horizontal: 'center',
vertical: 'top' // 菜单从顶部中心展开
},
variant: 'menu' // 菜单变体
};
export { useStyles, MenuProps };2.1 useStylesmakeStyles 是 Material-UI 提供的用于创建 CSS-in-JS 样式的方法。这里定义了表单控制的宽度、不确定状态复选框的颜色、全选文本的字体样式以及全选选项的背景色。
2.2 MenuPropsMenuProps 对象用于配置 Select 组件下拉菜单的显示行为。它包括:
要在应用中使用 MultiSelectWithCheckbox 组件,您需要在父组件中管理其 value 状态。
import React, { useState } from 'react';
import MultiSelectWithCheckbox from './MultiSelectWithCheckbox'; // 假设路径正确
function App() {
const options = ['Option 1', 'Option 2', 'Option 3', 'Option 4', 'Option 5'];
const [selectedOptions, setSelectedOptions] = useState([]);
const handleOptionsChange = (newOptions) => {
setSelectedOptions(newOptions);
};
return (
<div style={{ padding: 20, width: 300 }}>
<h1>多选组件示例</h1>
<MultiSelectWithCheckbox
label="选择你的选项"
options={options}
value={selectedOptions}
onChange={handleOptionsChange}
/>
<p>当前已选择: {selectedOptions.length > 0 ? selectedOptions.join(', ') : '无'}</p>
</div>
);
}
export default App;在这个示例中,App 组件维护了 selectedOptions 状态,并将其作为 value prop 传递给 MultiSelectWithCheckbox。当用户在多选组件中进行选择时,handleOptionsChange 会更新 selectedOptions 状态,从而使组件保持受控。
通过上述步骤和代码示例,您应该能够成功地在 Material-UI 应用中实现一个功能完善且用户友好的多选组件,支持“全选”和“取消全选”功能,并具备智能的标签动态切换。
以上就是Material-UI 多选组件:实现全选/取消全选与标签动态切换的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号