多级表单的组件目录
总的组件useMutilForm。hooks的写法
import { ReactElement, useState } from 'react'
export function useMutilForm(steps: ReactElement[]) {
//组件控制上一步下一步
const [currntStepIndex, setCurrntStepIndex] = useState(0)
function next() {
// 判断边界值
if (currntStepIndex === steps.length - 1) {
return
}
setCurrntStepIndex(currntStepIndex + 1)
}
function prev() {
// 判断边界值
if (currntStepIndex === 0) {
return
}
setCurrntStepIndex(currntStepIndex - 1)
}
return {
currntStepIndex,
setCurrntStepIndex,
step: steps[currntStepIndex],
next,
prev,
isFirstStep: currntStepIndex === 0,
isLastStep: currntStepIndex === steps.length - 1,
}
}
app.tsx
import './App.css'
import { useMutilForm } from './views/mutilForm/useMutilFrom'
import { AddressForm } from './views/mutilForm/addressForm'
import { UserForm } from './views/mutilForm/userForm'
import { AccountForm } from './views/mutilForm/accountForm'
import { FormEvent, useState } from 'react'
const FormData = {
username: '',
password: '',
email: '',
name: ' ',
address: ' ',
vx: '',
}
function App() {
// 转成响应式数据
const [data, setData] = useState(FormData)
// 解构hooks的参数,通过数组形式去传组件
const { step, prev, next, isFirstStep, isLastStep } = useMutilForm([
<AddressForm {...data} changeValue={changeValue}></AddressForm>,
<UserForm></UserForm>,
<AccountForm></AccountForm>,
])
// 改变state
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function changeValue( value:any) {
setData((prev)=>{
return {...prev, ...value}
})
}
// 提交表单
function submit (e:FormEvent){
// 阻止表单默认行为
e.preventDefault()
if(!isLastStep) return next()
console.log('data', data)
}
return (
<div className="border p-2">
{step}
{!isFirstStep && <button onClick={prev}>上一个</button>}
<button onClick={submit}>{!isLastStep ? '下一个' : '完成'}</button>
</div>
)
}
export default App
其中一个子组件
import { FormWrapper } from './formWrapper'
type Address = { address: string; changeValue: (e: any) => void }
export function AddressForm({ address, changeValue }: Address) {
return (
// FormWrapper通用的组件容器
<FormWrapper title="地址信息">
<div className="flex">
<label>地址:</label>
<input
type="text"
autoFocus
required
value={address}
onChange={(e) => changeValue({ address: e.target.value })}
/>
</div>
</FormWrapper>
)
}
通用的组件容器
export function FormWrapper({ title,children }: { title:string,children: React.ReactNode }) {
return (
<div>
<p>{title}</p>
<div className="flex-col">{children}</div>
</div>
);
}
总结:
1.采用hooks组件的写法,把组件放在数组里面,解构拿到组件的变量和方法
const { step, prev, next, isFirstStep, isLastStep } = useMutilForm([
<AddressForm {...data} changeValue={changeValue}></AddressForm>,
<UserForm></UserForm>,
<AccountForm></AccountForm>,
])
2.通用的容器提取成组件,通过children进行子组件展示
3.父组件拿到子组件的{key:value}进行解构重新赋值
setData((prev)=>{
return {...prev, ...value}
})