react-vmodel 搞定双向绑定,超简单

159 阅读1分钟
像vue v-model一样简单,告别繁琐深层的set{...data,sub:{...data.sub,haha:'here'}}

安装

    npm install react-vmodel

完整实例

npx degit https://github.com/leafio/react-vmodel/examples react-vmodel-examples

用法

绑定组件

import { makeVModel ,useVModel} from 'react-vmodel'
export default function Demo() {
    const [data,setData]=useState(
        { name:'example',
         tasks:[{id:1,name:'test'}]
        }
    )
    const vModel=makeVModel(data,setData)

    // 或者使用 `useVmodel` hook定义
    // const [vModel,data,setData]=useVModel({
    //   { name:'example',
    //      tasks:[{id:1,name:'test'}]
    //     }
    // )
    return<>  
     {/* 完整绑定,使用 react-vmodel */}
        <CustomComponent {...vModel()}/>
     {/* //不使用 */}
        <CustomComponent value={data} onChange={(e)=>{
             setData(e.target?e.target.value:e)
         }}/>
 
     {/* //key值绑定  使用react-vmodel */}
        <CustomComponent2 {...vModel("tasks[0].name")}/>
     {/* //--不使用 */}
        <CustomComponent2
            value={data.tasks[0].name}
            onChange={(e) => {
                const clone = structuredClone(data);
                clone.tasks[0].name = e.target?e.target.value:e;
                setData(clone);
            }}
     />  
    </>
 }

绑定input输入框

文本框
import { makeVModel } from 'react-vmodel'
export default function Demo() {
   const [text,setText]=useState('Hello World')
   const vModel=makeVModel(text,setText)
   return<>
    <input {...vModel()}></input>
    {/* //trim */}
    <input {...vModel.trim()}></input>

    {/* //number */}
     <input type="number" {...vModel()}></input>
     {/* //or */}
     <input  {...vModel.number()}></input>
   </>
}
多选框Checkbox
True-False
import { makeVModel } from 'react-vmodel'
export default function Demo() {
   const [checked,setChecked]=useState(false)
   const vModel=makeVModel(checked,setChecked)
   return<>
    {/* //true-false */}
    <input type='checkbox' {...vModel.checked()}></input>

    {/* //true 1   false 0 */}
     <input type='checkbox' {...vModel.checked({trueValue:1,falseValue:0})}></input>
   </>
}
CheckedList
import { makeVModel } from "react-vmodel"
export default function Demo() {
    const [checkedList, setCheckedList] = useState([])
    const vModel = makeVModel(checkedList, setCheckedList)
    return (
        <>
            {["one", "two", "three"].map((op) => (
                <input
                    key={op}
                    type="checkbox"
                    {...vModel.checklist({ value: op })}
                ></input>
            ))}
        </>
    )
}
单选框Radio
import { makeVModel } from "react-vmodel"
export default function Demo() {
    const [selected, setSelected] = useState("")
    const vModel = makeVModel(selected, setSelected)
    return (
        <>
            {["one", "two", "three"].map((op) => (
                <input
                    key={op}
                    type="radio"
                    {...vModel.checked({ value: op })}
                ></input>
            ))}
        </>
    )
}
下拉框Select
import { makeVModel } from "react-vmodel"
export default function Demo() {
    const [selected, setSelected] = useState("")
    const vModel = makeVModel(selected, setSelected)
    return (
        <>
            {
                <select {...vModel()}>
                    {["one", "two", "three"].map((op) => {
                        return (
                            <option key={op} value={op}>
                                {op}
                            </option>
                        )
                    })}
                </select>
            }
        </>
    )
}

高级用法

import { makeVModel } from 'react-vmodel'
export default function Demo() {
   const [checked,setChecked]=useState(false)
   const vModel=makeVModel(checked,setChecked)
   return<>
    {/* //true 1   false 0 */}
     <input type='checkbox' {...vModel.checked({trueValue:1,falseValue:0})}></input>

     {/* 自定义,同样实现上面的功能 */}
    <input type='checkbox' {...vModel((value, onChange) => ({
        checked: value === 1,
        value:String(value===1),
        onChange: (e) => onChange(e.target.checked ? 1 : 0)
    }))} />
   </>
}