0.1.1 • Published 2 months ago

react-vmodel v0.1.1

Weekly downloads
-
License
MIT
Repository
-
Last release
2 months ago

react-vmodel

A vue v-model similar usage for react . Easy to access deep path with ts prompt. npm.io

Usage

Bind to Component

import { makeVModel } from 'react-vmodel'
export default function Demo() {
   const [data,setData]=useState({
    name:'example'
    tasks:[
        {
            id:1,
            name:'test'
        }
    ]
   })
   const vModel=makeVModel(data,setData)
   return<>
   {
    // All Bind with react-vmodel
    <CustomComponent {...vModel()}/>
    //--not with
    <CustomComponent value={data} onChange={(e)=>{
        setData(e.target?e.target.value:e)
        }}
    />

    //Path Bind with react-vmodel
     <CustomComponent2 {...vModel('tasks[0].name')}/>
     //--not with
    <CustomComponent2
        value={data.tasks[0].name}
        onChange={(e) => {
            const clone = structuredClone(data);
            clone.tasks[0].name = e.target?e.target.value:e;
            setData(clone);
        }}
    />
   }
   </>

}

Bind to input

Text
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>
            }
        </>
    )
}

Full Example

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

Vanilla Form

import { useEffect, useState } from "react"
import { makeVModel } from "react-vmodel"
export default function DemoVanilla() {
    const [form, setForm] = useState({
        name: "demo",
        gender: "male",
        hobbies: [],
        job: {
            id: 0,
            year: 1,
        },
        projects: [
            {
                name: "First",
                isFinished: 1,
            },
            {
                name: "Last",
                isFinished: 0,
            },
        ],
    })

    const vModel = makeVModel(form, setForm)
    useEffect(() => {
        console.log(form)
    })
    return (
        <form className="flex flex-col ">
            <label className="mb-1">
                <span className="w-24 inline-block">Name:</span>
                <input type="text" className=" border" {...vModel("name")} />
            </label>

            <div className="mb-1">
                <span className="w-24 inline-block">Gender:</span>
                <label>
                    Male
                    <input
                        type="radio"
                        className=" border"
                        {...vModel.checked("gender", { value: "male" })}
                    />
                </label>
                <label>
                    Female
                    <input
                        type="radio"
                        className=" border"
                        {...vModel.checked("gender", { value: "female" })}
                    />
                </label>
            </div>
            <label className="mb-1">
                <span className="w-24 inline-block">Hobbies:</span>
                {hobbyOptions.map((h) => (
                    <label key={h}>
                        {h}
                        <input
                            type="checkbox"
                            className=" border"
                            {...vModel.checklist("hobbies", { value: h })}
                        />
                    </label>
                ))}
            </label>
            <label className="mb-1">
                <span className="w-24 inline-block">Job:</span>
                <select {...vModel.number("job.id")}>
                    {jobOptions.map((job) => {
                        return (
                            <option key={job.value} value={job.value}>
                                {job.label}
                            </option>
                        )
                    })}
                </select>
            </label>
            <label className="mb-1">
                <span className="w-24 inline-block">Experience:</span>
                <input
                    type="number"
                    className=" border"
                    {...vModel("job.year")}
                />
            </label>
            <div className="mb-1">
                <span className="w-24 inline-block">Projects:</span>
                {form.projects.map((p, index) => (
                    <label key={p.name}>
                        <span>{p.name}</span>
                        <input
                            type="checkbox"
                            {...vModel.checked(
                                `projects[${index}].isFinished`,
                                { trueValue: 1, falseValue: 0 }
                            )}
                        />
                    </label>
                ))}
            </div>
        </form>
    )
}
const hobbyOptions = ["film", "sports", "music"]
const jobOptions = [
    {
        label: "Front End Developer",
        value: 0,
    },
    {
        label: "Back End Developer",
        value: 1,
    },
    {
        label: "Test Engineer",
        value: 2,
    },
]

Ant Design

import { Checkbox, Form, Input, InputNumber, Radio, Select, Switch } from "antd"
import { useEffect, useState } from "react"
import { makeVModel } from "react-vmodel"
export default function DemoAntd() {
    const [form, setForm] = useState({
        name: "demo",
        join: "yes",
        gender: "male",
        hobbies: [],
        job: {
            id: 0,
            year: 1,
        },
        projects: [
            {
                name: "First",
                isFinished: 1,
            },
            {
                name: "Last",
                isFinished: 0,
            },
        ],
    })

    const vModel = makeVModel(form, setForm)
    useEffect(() => {
        console.log(form)
    })
    return (
        <Form
            className="flex flex-col "
            labelCol={{ span: 4 }}
            labelAlign="left"
        >
            <Form.Item label="Name:">
                <Input type="text" {...vModel("name")} />
            </Form.Item>
            <Form.Item label="Join:">
                <Switch
                    {...vModel.checked("join", {
                        trueValue: "yes",
                        falseValue: "no",
                    })}
                />
            </Form.Item>
            <div className="mb-1">
                <Form.Item label="Gender:">
                    <Radio {...vModel.checked("gender", { value: "male" })}>
                        Male
                    </Radio>
                    <Radio {...vModel.checked("gender", { value: "female" })}>
                        Female
                    </Radio>
                </Form.Item>
            </div>

            <Form.Item label="Hobbies">
                {hobbyOptions.map((h) => (
                    <Checkbox
                        key={h}
                        {...vModel.checklist("hobbies", { value: h })}
                    >
                        {h}
                    </Checkbox>
                ))}
            </Form.Item>

            <Form.Item label="Job">
                <Select {...vModel.number("job.id")} options={jobOptions} />
            </Form.Item>

            <Form.Item label="Experience">
                <InputNumber {...vModel("job.year")} />
            </Form.Item>

            <Form.Item label="Projects">
                {form.projects.map((p, index) => (
                    <Checkbox
                        key={p.name}
                        {...vModel.checked(`projects[${index}].isFinished`, {
                            trueValue: 1,
                            falseValue: 0,
                        })}
                    >
                        {p.name}{" "}
                    </Checkbox>
                ))}
            </Form.Item>
        </Form>
    )
}
const hobbyOptions = ["film", "sports", "music"]
const jobOptions = [
    {
        label: "Front End Developer",
        value: 0,
    },
    {
        label: "Back End Developer",
        value: 1,
    },
    {
        label: "Test Engineer",
        value: 2,
    },
]

Material UI

import {
    Checkbox,
    FormControl,
    FormControlLabel,
    FormLabel,
    Input,
    MenuItem,
    Radio,
    Select,
    Switch,
} from "@mui/material"
import { useEffect, useState } from "react"
import { makeVModel } from "react-vmodel"
export default function DemoMui() {
    const [form, setForm] = useState({
        name: "demo",
        join: "yes",
        gender: "male",
        hobbies: [],
        job: {
            id: 0,
            year: 1,
        },
        projects: [
            {
                name: "First",
                isFinished: 1,
            },
            {
                name: "Last",
                isFinished: 0,
            },
        ],
    })

    const vModel = makeVModel(form, setForm)
    useEffect(() => {
        console.log(form)
    })
    return (
        <form className="flex flex-col ">
            <FormControl>
                <FormLabel>Name:</FormLabel>
                <Input type="text" {...vModel("name")} />
            </FormControl>
            <FormControl>
                <FormLabel>Join:</FormLabel>
                <Switch
                    {...vModel.checked("join", {
                        trueValue: "yes",
                        falseValue: "no",
                    })}
                />
            </FormControl>
            <FormControl>
                <FormLabel>Gender:</FormLabel>
                <div className="flex">
                    <FormControlLabel
                        label={"Male"}
                        control={
                            <Radio
                                {...vModel.checked("gender", {
                                    value: "male",
                                })}
                            />
                        }
                    />
                    <FormControlLabel
                        label={"Female"}
                        control={
                            <Radio
                                {...vModel.checked("gender", {
                                    value: "female",
                                })}
                            />
                        }
                    />
                </div>
            </FormControl>
            <FormControl>
                <FormLabel>Hobbies:</FormLabel>
                <div className="flex">
                    {hobbyOptions.map((h) => (
                        <FormControlLabel
                            key={h}
                            label={h}
                            control={
                                <Checkbox
                                    {...vModel.checklist("hobbies", {
                                        value: h,
                                    })}
                                />
                            }
                        />
                    ))}
                </div>
            </FormControl>
            <FormControl>
                <FormLabel>Job:</FormLabel>
                <Select {...vModel.number("job.id")}>
                    {jobOptions.map((job) => {
                        return (
                            <MenuItem key={job.value} value={job.value}>
                                {job.label}
                            </MenuItem>
                        )
                    })}
                </Select>
            </FormControl>
            <FormControl>
                <FormLabel>Experience:</FormLabel>
                <Input type="number" {...vModel("job.year")} />
            </FormControl>
            <FormControl>
                <FormLabel>Projects:</FormLabel>
                <div className="flex">
                    {form.projects.map((p, index) => (
                        <FormControlLabel
                            key={p.name}
                            label={p.name}
                            control={
                                <Checkbox
                                    {...vModel.checked(
                                        `projects[${index}].isFinished`,
                                        { trueValue: 1, falseValue: 0 }
                                    )}
                                />
                            }
                        />
                    ))}
                </div>
            </FormControl>
        </form>
    )
}
const hobbyOptions = ["film", "sports", "music"]
const jobOptions = [
    {
        label: "Front End Developer",
        value: 0,
    },
    {
        label: "Back End Developer",
        value: 1,
    },
    {
        label: "Test Engineer",
        value: 2,
    },
]

Installation

    npm install react-vmodel
0.1.1

2 months ago

0.1.0

2 months ago

0.0.4

6 months ago

0.0.3

7 months ago

0.0.2

7 months ago

0.0.1

7 months ago

1.0.0

1 year ago