Stepper 通过编号的步骤传达进度,它提供了类似向导的工作流程。
他除了有前面提到的 Tabs 的属性外还有提供纪录进度的功能,可以通过将当前步进索引(从零开始)作为 activeStep 属性传递来控制步进器,Stepper方向是使用 orientation 属性设置的,所以如果要调整成垂直的状态只要设置成 orientation="vertical",alternativeLabel 属性则可以让标签的位置改再 icon 之下。
// 先设置step title
function getSteps() {
return ['基本资料', '选择商品型号', '配送资讯'];
}
// 再设置step content,可以用其他组件来替换
function getStepContent(stepIndex) {
switch (stepIndex) {
case 0:
return '基本资料页面...';
case 1:
return '选择商品型号页面...';
case 2:
return '配送资讯...';
default:
return 'step 未设定';
}
}
// in export function
const [activeStep, setActiveStep] = React.useState(0);
const steps = getSteps();
const handleNext = () => {
setActiveStep((prevActiveStep) => prevActiveStep + 1);
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
const handleReset = () => {
setActiveStep(0);
};
/*in return*/
<div className={classes.root}>
<Stepper activeStep={activeStep} alternativeLabel>
{steps.map((label) => (
<Step key={label}>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
<div>
{activeStep === steps.length ? (
<div>
<Typography className={classes.instructions}>填写完毕</Typography>
<Button onClick={handleReset}>重置</Button>
</div>
) : (
<div>
<Typography className={classes.instructions}>{getStepContent(activeStep)}</Typography>
<div>
<Button
disabled={activeStep === 0}
onClick={handleBack}
className={classes.backButton}
>
上一步
</Button>
<Button variant="contained" color="primary" onClick={handleNext}>
{activeStep === steps.length - 1 ? '完成' : '下一步'}
</Button>
</div>
</div>
)}
</div>
</div>
官网文件上有提供Skip的范例做法:
// ...前面的段落一样
// in export function
const classes = useStyles();
const [activeStep, setActiveStep] = React.useState(0);
const [skipped, setSkipped] = React.useState(new Set());
const isStepOptional = (step) => {
return step === 1;
};
const isStepSkipped = (step) => {
return skipped.has(step);
};
const handleNext = () => {
let newSkipped = skipped;
if (isStepSkipped(activeStep)) {
newSkipped = new Set(newSkipped.values());
newSkipped.delete(activeStep);
}
setActiveStep((prevActiveStep) => prevActiveStep + 1);
setSkipped(newSkipped);
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
const handleSkip = () => {
if (!isStepOptional(activeStep)) {
// 需要防范此情形,一般的使用情境下不太容易发生
throw new Error("You can't skip a step that isn't optional.");
}
setActiveStep((prevActiveStep) => prevActiveStep + 1);
setSkipped((prevSkipped) => {
const newSkipped = new Set(prevSkipped.values());
newSkipped.add(activeStep);
return newSkipped;
});
};
const handleReset = () => {
setActiveStep(0);
};
<div className={classes.root}>
<Stepper activeStep={activeStep}>
{steps.map((label, index) => {
const stepProps = {};
const labelProps = {};
if (isStepOptional(index)) {
labelProps.optional =
<Typography variant="caption">
Optional
</Typography>;
}
if (isStepSkipped(index)) {
stepProps.completed = false;
}
return (
<Step key={label} {...stepProps}>
<StepLabel {...labelProps}>{label}</StepLabel>
</Step>
);
})}
</Stepper>
<div>
{activeStep === steps.length ? (
<div>
<Typography className={classes.instructions}>
All steps completed - you're finished
</Typography>
<Button onClick={handleReset} className={classes.button}>
Reset
</Button>
</div>
) : (
<div>
<Typography className={classes.instructions}>
{getStepContent(activeStep)}
</Typography>
<div>
<Button
disabled={activeStep === 0}
onClick={handleBack}
className={classes.button}
>
Back
</Button>
{isStepOptional(activeStep) && (
<Button
variant="contained"
color="primary"
onClick={handleSkip}
className={classes.button}
>
Skip
</Button>
)}
<Button
variant="contained"
color="primary"
onClick={handleNext}
className={classes.button}
>
{activeStep === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
)}
</div>
</div>
可以依照实际的情况去修改逻辑,这个作法不是固定的。
设定 nonLinear 属性,可以让进程的线不亮。
<Stepper activeStep={activeStep} nonLinear alternativeLabel>
{steps.map((label) => (
<Step key={label}>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
另外还有类似 Carousel 的范例在官方的文件上,这里我就不再赘述他的用法了,因为我相信通常在处理这种 lightbox 的东西会去用类似 splidejs 这种专门的套件,可能会比较方便一些。
那麽今天的内容就到这里了,明天会讲解 Menu 组件的用法。
<<: [Day 16] IOCP Input/Output Completion Port
今天要介绍的是如何改变按钮的外观( 圆角、边线 ) 成品: 刻好画面後,在 ViewControll...
今天要提到一些关於 GitHub Action 内撰写 YAML 一些技巧,环境变数 (Enviro...
当我们在写函式库或框架的时候,通常表示这段逻辑很常用到,希望藉由抽取成函式库或框架来重复使用,减少重...
Object content Array 是一种 Object,所以我们也能够用 key valu...
第二天的课程对於没有写过网页的我有一点难度,主要是网页的架构不像数据直线的思考,整个架构颇立体的, ...