v-model / r-model
这页直接对齐 v-on 页面:一边给真实 Rue TSX 写法,一边给手写 value / checked / modelValue 的等价实现,预览里也直接跑真实 v-model / r-model。
左列是当前真实可写进 TSX 的 v-model / r-model,右列是手写等价实现。组件部分则把真实指令预览和等价 props 写法并排展示。
原生输入:真实指令 vs 手写等价
directivemanual
Rue TSX 实际写法
v-model / r-modelmessage: Rue model
trimmed: keep edges tidy
age: 18
lazy: blur to sync
accepted: false
手写 value / checked 对照
manualmessage: Rue model
trimmed: keep edges tidy
age: 18
lazy: blur to sync
accepted: false
组件:真实 v-model vs 等价 props
component compareRue TSX 实际组件写法
v-modeltitle: Guide draft
articleTitle: Inside Rue
firstName / lastName: Rue JSX
等价手写 props
modelValue / onUpdateXxximport { type FC, ref } from '@rue-js/rue'
type ModelFieldProps = {
label: string
modelValue?: string
onUpdateModelValue?: (value: string) => void
}
const ModelField: FC<ModelFieldProps> = props => (
<label className="floating-label">
<input
className="input input-bordered w-full"
value={props.modelValue ?? ''}
onInput={(event: Event) => {
props.onUpdateModelValue?.((event.target as HTMLInputElement).value)
}}
/>
<span>{props.label}</span>
</label>
)
type TitleFieldProps = {
title?: string
titleModifiers?: { trim?: boolean; lazy?: boolean }
onUpdateTitle?: (value: string) => void
}
const TitleField: FC<TitleFieldProps> = props => {
const emitTitleUpdate = (event: Event) => {
const rawValue = (event.target as HTMLInputElement).value
props.onUpdateTitle?.(props.titleModifiers?.trim ? rawValue.trim() : rawValue)
}
return (
<input
className="input input-bordered"
value={props.title ?? ''}
onInput={props.titleModifiers?.lazy ? undefined : emitTitleUpdate}
onChange={props.titleModifiers?.lazy ? emitTitleUpdate : undefined}
/>
)
}
type UserNameEditorProps = {
firstName?: string
lastName?: string
firstNameModifiers?: { trim?: boolean; lazy?: boolean }
lastNameModifiers?: { trim?: boolean; lazy?: boolean }
onUpdateFirstName?: (value: string) => void
onUpdateLastName?: (value: string) => void
}
const UserNameEditor: FC<UserNameEditorProps> = props => {
const emitFirstNameUpdate = (event: Event) => {
const rawValue = (event.target as HTMLInputElement).value
props.onUpdateFirstName?.(props.firstNameModifiers?.trim ? rawValue.trim() : rawValue)
}
const emitLastNameUpdate = (event: Event) => {
const rawValue = (event.target as HTMLInputElement).value
props.onUpdateLastName?.(props.lastNameModifiers?.trim ? rawValue.trim() : rawValue)
}
return (
<div className="grid gap-3 md:grid-cols-2">
<input
className="input input-bordered"
value={props.firstName ?? ''}
onInput={props.firstNameModifiers?.lazy ? undefined : emitFirstNameUpdate}
onChange={props.firstNameModifiers?.lazy ? emitFirstNameUpdate : undefined}
/>
<input
className="input input-bordered"
value={props.lastName ?? ''}
onInput={props.lastNameModifiers?.lazy ? undefined : emitLastNameUpdate}
onChange={props.lastNameModifiers?.lazy ? emitLastNameUpdate : undefined}
/>
</div>
)
}
const Demo: FC = () => {
const title = ref('Guide draft')
const articleTitle = ref('Inside Rue')
const firstName = ref('Rue')
const lastName = ref('JSX')
return (
<section className="grid gap-6">
<div className="grid gap-3">
<ModelField label="默认组件 model" v-model={title.value} />
<TitleField v-model:trim-title={articleTitle.value} />
<UserNameEditor
v-model:trim-first-name={firstName.value}
v-model:lazy-last-name={lastName.value}
/>
</div>
<div className="grid gap-3">
<ModelField
label="默认组件 model"
modelValue={title.value}
onUpdateModelValue={value => {
title.value = value
}}
/>
<TitleField
title={articleTitle.value}
titleModifiers={{ trim: true }}
onUpdateTitle={value => {
articleTitle.value = value
}}
/>
<UserNameEditor
firstName={firstName.value}
lastName={lastName.value}
firstNameModifiers={{ trim: true }}
lastNameModifiers={{ lazy: true }}
onUpdateFirstName={value => {
firstName.value = value
}}
onUpdateLastName={value => {
lastName.value = value
}}
/>
</div>
</section>
)
}
export default Demov-model-> modelValue + onUpdateModelValue
v-model:trim-title-> title + titleModifiers + onUpdateTitle
v-model:trim-first-name-> firstName + firstNameModifiers + onUpdateFirstName
v-model:lazy-last-name-> lastName + lastNameModifiers + onUpdateLastName